Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Specify sub directory for all the generated assets for easy deploy and serve #233

Closed
npup opened this Issue Dec 12, 2017 · 24 comments

Comments

Projects
@npup
Copy link

npup commented Dec 12, 2017

TLDR;

My point is that serving the built project (both in prod and dev) could be so much easier in the common case if generated assets were not necessarily put alongside the main index file -- and an option for it could carry its weight.

What am I talking about?

Consider having a src/index.html file, referring css and js files (living anywhere in the src tree).
Without any options used when bundling the resulting assets are generated alongside the index.html in ./dist/ like:

dist/
  index.html
  50c20e2a4174028d1e9d4574129f6104.css
  50c20e2a4174028d1e9d4574129f6104.js

-- and the index.html is rewritten to refer them nicely.

SPA stylee, the dist folder is to be statically served by nginx/equivalent, and for a seamless dev experience I'd like to deploy it as is -- or even build it in place on Heroku or such.

For that, I would love a build option to say "all the generated assets should live in a sub directory by the name of foo". (We already have an output-dir option, which sets the name of the whole build output, and a public-url option, though the latter just affects the referring paths in index.html (in this case) ).

This could the the result of my idea:

dist/
  index.html
  foo/
    50c20e2a4174028d1e9d4574129f6104.css
    50c20e2a4174028d1e9d4574129f6104.js

That way nginx/whatever could happily serve index.html for all requests but foo and under.

An alternative would be

  • using the public-url option to have index.html refer assets in foo
  • having a post build step to "manually" move asset files to dist/foo

, but this juggling does not work very well in development mode, wanting nginx to serve files in the same manner from the local dist/.

Creating a more elaborate bunch of rules for the file server to have it avoid serving index for any generated asset file is another cumbersome route I'd happily avoid :D .

@davidnagli davidnagli changed the title Feature: Specify sub directory for all the generated assets for easy SPA deploy and serve [RFC] Specify sub directory for all the generated assets for easy SPA deploy and serve Dec 12, 2017

@davidnagli davidnagli added this to Discussion in RFC via automation Dec 12, 2017

@davidnagli

This comment has been minimized.

Copy link
Member

davidnagli commented Dec 12, 2017

Is this essential to making SPAs? Can we avoid having to add more to our CLI by just letting NGINX handel all of this rather than parcel?

@npup

This comment has been minimized.

Copy link
Author

npup commented Dec 12, 2017

@davidnagli
Thanks for chiming in!

An SPA was my initial use case (and used in my example), though I'd like to see it as a generally nice feature just to to be able to say where my generated files shall end up.
If we are talking developer experience, this is really quite helpful (for other post processing too!). Hey, in comparison, the output-diroption does not help as much, but it is still there ;).

As for the SPA case -- leaving the generated structure flat with no options (leaving the web server to handle this) is really not very ergonomic in the general case. Again, makes for a really smooth developer experience, which is something I sensed is a goal of this cool tool.

@davidnagli

This comment has been minimized.

Copy link
Member

davidnagli commented Dec 12, 2017

Ya I definetly see where you’re going with this. It seems like a pretty important feature.

How do you think we should implement this?

The whole point of Parcel is that there is no configure file, so we would want to implement it in a way that’s very automatic. I just can’t figure out how to design it in a way that is actually easy and productive for developers.

@mrbar42

This comment has been minimized.

Copy link

mrbar42 commented Dec 13, 2017

wouldn't nginx's try_files directive solve the problem?

location / {
    try_files $uri /index.html;
}

this will make nginx to try and serve a file under the request uri and otherwise fallback to index.html

it might be worth creating a guide for such case for common web servers.

@npup

This comment has been minimized.

Copy link
Author

npup commented Dec 13, 2017

@mrbar42 that's a nice one, but nginx and/or SPA are not the only reasons to need the generated files/assets to be easily distinguished in the general case -- be it in the form of naming a directory for them or having the files prefixed or whatever.

@davidnagli What would the major problem be with a cli option like the existing public-url and output-dir, that makes the generated files land (and be referenced) in a directory with a certain name?

@npup npup changed the title [RFC] Specify sub directory for all the generated assets for easy SPA deploy and serve [RFC] Specify sub directory for all the generated assets for eas deploy and serve Dec 16, 2017

@npup npup changed the title [RFC] Specify sub directory for all the generated assets for eas deploy and serve [RFC] Specify sub directory for all the generated assets for easy deploy and serve Dec 16, 2017

@davidnagli

This comment has been minimized.

Copy link
Member

davidnagli commented Dec 16, 2017

From an SPA development perspective, is it essential that we give you control over the name of that directory (/foo in your example)? Can we just throw all the generated bundles into a subdirectory called bundles or something?

@npup

This comment has been minimized.

Copy link
Author

npup commented Dec 18, 2017

@davidnagli That would be the next best thing I suppose (and not only for SPA use cases, sorry if that part of my argument stuck), in that it facilitates various post build operations. I really can see (and appreciate) the effort to keep the configuration explosion on a leash.

Though I foresee continuous proposals about being able to name the bundles dir too, especially since one already can set the name of the main output dir. Let's see what happens :)

@davidnagli davidnagli added the SPA label Dec 19, 2017

@highsea

This comment has been minimized.

Copy link

highsea commented Jan 10, 2018

I also have the same problem:

parcel Can not be configured html, js, css such as multiple files, output to multiple directories /views/dist, public/assets/js/hash.js, public/assets/css/hash.css

For example, the following is the file structure of the backend rendering project based on express

├── README.md
├── app.js
├── config.js
├── middlewares
│   ├── auth
│   ├── csrf
│   ├── jwt
│   └── util
├── public
│   ├── assets
│   │   ├── css
│   │   ├── img
│   │   └── js
│   └── debugger
│       ├── css
│       ├── img
│       └── js
├── ssl
└── views
    ├── dist
    └── src
        ├── index.html
        └── layer.html

parcel build /views/src/index.html -d /views/dist/index.html --public-url /assets/js ?

parcel is great, packaging efficiency is very fast, but it can not configure the corresponding file path, a bit regrettable... But I'll still pay attention to it

@jamiegdsn

This comment has been minimized.

Copy link

jamiegdsn commented May 12, 2018

Is this still not possible? I have a Flask app with the following structure:

├───main.py
├───package.json
├───js
│   ├───app.js
│   └───utilities.js
├───sass
│   ├───base.scss
│   ├───home.scss
│   └───vars.scss
├───static
│   ├───images
│   ├───scripts
│   └───style
└───templates
    └───index.html

By default, Flask apps serve static content (js, css, images, etc) from static/ and html files from templates/.

I want Parcel to bundle the files from js/ and sass/ into static/scripts/ and static/style/ respectively. templates/index.html should also be updated to reference these files.

Currently everything is put into a dist/ folder, losing all structure. Is there are workaround for this?

Ideally, to cater for all types of projects, it should be possible to specify different output directories for different entry points. In Webpack, you can specify to output css into path/a/, js into another/path/b/, and html into c/ (for example).

@staghouse

This comment has been minimized.

Copy link

staghouse commented Aug 7, 2018

Would love to see some official word on this. I don't find much sense for a project where the index.html is the build entry point and all the assets are just grouped together and outted to the same directory. I don't find this to be a practical, useful or even standard approach to file organization across any language or project.

This is the one issue where I find Parcel's "no config" approach to be a fatal flaw as it basically defines how all projects must be structured and does so without any logic.

@hacknug

This comment has been minimized.

Copy link

hacknug commented Aug 8, 2018

Imho Parcel should recreate the existing project structure for imported files. This would allow infinite flexibility (users could just do whatever and it would work for them) and it could always be overwritten using a config file.

@designalchemy

This comment has been minimized.

Copy link

designalchemy commented Aug 10, 2018

This would be useful for me too, maybe even a /assets/ folder or anything similar so when i have 200 + images they arnt all in the root

@Place1

This comment has been minimized.

Copy link

Place1 commented Aug 14, 2018

I've run into this limitation today.
I'm using parcel to build my express app which is server side renderering a react app.

I was about to add this line to the express app:

app.use(express.static(path.join(__dirname)));

to serve all the web-app assets but clearly this would be really bad because with the build folder being flat that means GET /index.js would return my server side code!

@mrbar42

This comment has been minimized.

Copy link

mrbar42 commented Aug 14, 2018

@Place1 how would that happen? do you store your index.js in the dist folder?

if your project looks like this

-/
 - dist/
   - *.{html,js,css,png,woff2,...}
 - index.js

then you should do something like this

app.use(express.static(path.join('dist')));

which wouldn't expose your server code

@Place1

This comment has been minimized.

Copy link

Place1 commented Aug 14, 2018

@mrbar42

This comment has been minimized.

Copy link

mrbar42 commented Aug 14, 2018

I run my backend through parcel to concert jsx using —target=node

then you can call parcel twice with different out-dir, once for the clinet with dist/client and once with dist/server
and have your express static point dist/client

@Place1

This comment has been minimized.

Copy link

Place1 commented Aug 15, 2018

@kshep92

This comment has been minimized.

Copy link

kshep92 commented Aug 21, 2018

I was surprised to see that if I have a folder structure:

src
  index.html
    css/style.css
    js/app.js

Everything would just be dumped out in a flat file structure in the dist folder. It would be nice if the dist folder followed the same structure as my src folder. Not sure if this is what @hacknug meant.

@hacknug

This comment has been minimized.

Copy link

hacknug commented Aug 21, 2018

Yes! This is exactly what I meant.

@DeMoorJasper

This comment has been minimized.

Copy link
Member

DeMoorJasper commented Aug 21, 2018

It's hard to make this the standard as you could end up having a very deeply nested tree. And in most cases it just gets dumped onto a server anyways, besides that some terminal magic and you can find any file in seconds no matter how flat and big the folder is.

Note: this will be possible once parcel 2 gets released as you'll be able to use your own naming strategy (or a premade one {the default will remain the same}), this will allow anyone to use hashes, filenames and folders however they want

@devongovett

This comment has been minimized.

Copy link
Member

devongovett commented Nov 4, 2018

I don't think we'll support recreating the entire source file structure as it could be quite deep and nested as Jasper mentioned. I could see supporting a single "assets" directory where content hashed files could go, with other entry points at the top.

That being said, in Parcel 2 you'll be able to override the naming strategy using plugins, so I assume the community will come up with some good options for different use cases which we can bring back into core as needed.

@devongovett

This comment has been minimized.

Copy link
Member

devongovett commented Dec 16, 2018

Closing this since it will be solved in Parcel 2 via plugins.

RFC automation moved this from Discussion to Done Dec 16, 2018

t--takai added a commit to daisuke85a/bingo that referenced this issue Feb 11, 2019

開発コマンドを追加
ディレクトリ分けは現在のバージョンでは対応不可。
次のv2から対応できるみたいです。
parcel-bundler/parcel#233
@rafaelcichocki

This comment has been minimized.

Copy link

rafaelcichocki commented Feb 27, 2019

I would like to add a possible solution to create high-level asset folders:

|---/js
|    |---index.js
|---/css
|    |---index.css
|---/assets
|    |---/fonts
|    |    |---font1.woff2
|    |    |---font2.woff2

parcel build js/index.js assets/fonts/* css/index.css

which creates:

|---/dist
|    |---/js
|    |    |---index.js
|    |---/css
|    |    |---index.css
|    |---/assets
|    |    |---/fonts
|    |    |    |---font1.woff2
|    |    |    |---font2.woff2
@Lcfvs

This comment has been minimized.

Copy link

Lcfvs commented Mar 8, 2019

My plugin makes it, based on the publicURL : https://www.npmjs.com/package/parcel-plugin-pre-dist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.