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

Including images from the 'static' dir to a CLI generated Webpack project results in duplication in output bundle #968

Open
chrisckc opened this issue Nov 7, 2018 · 7 comments

Comments

@chrisckc
Copy link
Contributor

chrisckc commented Nov 7, 2018

I'm submitting a bug report
Here is another issue with the CLI generated webpack config that soon becomes apparent once an app starts to be built.

  • Loader/bundler:
    Webpack

Current behavior:
If you go down the logical steps needed to include an image in your app, ie. add an image inside 'static/images' dir then add the image to your html file like this:

 <img src="../static/images/test.png"

After running 'au build --env prod` and inspecting the contents of the 'dist' dir you will discover that the image has been included twice.

You will see it in it's correct form as a hashed filename such as "904ca927cf30ddc1d7dbbd6593f2f78e.png" as generated by the webpack url-loader plugin.

You will also see it at "images/test.png" as it is also copied over by the CopyWebpackPlugin which results in a second redundant copy.

The offending config entry is here:

...when(production || server, new CopyWebpackPlugin([
      { from: 'static', to: outDir }])),
  • What is the expected behavior?
    Expected that the image would not included in the output bundle twice.

To fix this issue, the config entry need to be changed to this:

// url-loader handles bundling of png/jpg/gif/svg etc.
// We only need to specify files here that are not referenced in the source files
...when(production || server, new CopyWebpackPlugin([
      { from: 'static/favicon.ico', to: 'favicon.ico' }])),

We only need to copy over the favicon as it is not referenced in the source so is not picked up by the webpack rules.

  • What is the motivation / use case for changing the behavior?
    To provide a better starting experience for new comers to Aurelia or Aurelia / webpack combination.

I am not new to Aurelia but new to webpack, and have so far had to spend quite some time sorting out issues with the webpack config to support various use cases. Simply following the path of using popular libraries such a jQuery or Bootstrap has proven to be problematic as i have detailed in another recent issue.

@Alexander-Taran
Copy link
Contributor

Questionable

@chrisckc
Copy link
Contributor Author

chrisckc commented Nov 8, 2018

Indeed, however if it is to be left as it is, there needs to be something in the docs that says something along the lines of "When including images that are referenced in the source, do not put them in the 'static' dir, instead either include them next to the source files or in another root directory such as /assets/" along with an explanation as to why this is necessary.

For example we could use a structure like this if an image is to be referenced in welcome.html
/src/views/welcome/welcome.ts
/src/views/welcome/welcome.html
/src/views/welcome/welcome.css
/src/views/welcome/test.png

Images shared between views could be placed here:
/src/images/

Although images are technically not source files, this would prevent the duplication issue.
Or they could be placed in an entirely different directory structure outside of src, next the 'static' dir, for example at /assets/images/

@chrisckc
Copy link
Contributor Author

chrisckc commented Nov 8, 2018

What i am saying above is basically what is described in the Vue.js webpack docs:
http://vuejs-templates.github.io/webpack/static.html

Regarding assets referenced i the source:

Since these assets may be inlined/copied/renamed during build, they are essentially part of your source code. This is why it is recommended to place Webpack-processed static assets inside /src, alongside other source files. In fact, you don't even have to put them all in /src/assets: you can organize them based on the module/component using them. For example, you can put each component in its own directory, with its static assets right next to it.

This way we can have both real static assets in the /static/ dir and webpack processed (renamed and hashed etc.) assets in /src/assets/

It would be great if the new/upcoming CLI generated skeleton templates included this kind of example structure with 2 sample images (one smaller than 8k and one larger) referenced to make it clear to new Aurelia/webpack devs how it is supposed to work.

@chrisckc
Copy link
Contributor Author

chrisckc commented Nov 8, 2018

The Vue CLI generated webpack config is much more comprehensive than the one generated by Aurelia CLI. The Vue webpack docs start off with a full description of the project structure:
http://vuejs-templates.github.io/webpack/structure.html
which makes it easy for newcomers using webpack to understand how it works and where to put things.

Going from zero to a working app is much quicker and easier if the basic structure is already well defined, configured and documented. I think this is one of the reasons that Aurelia struggles to gain traction in the face of it's competition.

@Alexander-Taran
Copy link
Contributor

are you using some plugin for webpack to process images?
if not.. why it touches them and produces hashed versions?
If yes.. then it is "src" because they are not static (-:

@Alexander-Taran
Copy link
Contributor

For documented webpack configs - I'm all in..
https://github.com/aurelia-contrib/aurelia-getting-started/tree/master/config-files/webpack
you are welcome to produce some (-:

@chrisckc
Copy link
Contributor Author

chrisckc commented Nov 8, 2018

I am using the section in the standard CLI generated config which uses url-loader for processing images.

I have been a fan of Aurelia ever since it came out and i am just trying to suggest ways to improve the starting experience for newcomers.

The point i am making is that the CLI generated project structure does not indicate to a newcomer where images should go, or rather that they should not go in the 'static' dir. Looking at the skeleton-typescript-webpack project does not help as styles.css is in the static dir, suggesting they go there.

The webpack config in skeleton-typescript-webpack uses this config instead which only copies the favicon:

new CopyWebpackPlugin([
      { from: 'static/favicon.ico', to: 'favicon.ico' }
    ]),

It also has styles.css in the 'static' dir, which is actually processed by the css-loader so is really a source file. If a newcomer generates a project with the CLI and then looks at the skeleton repo for some pointers and borrows some of the source and css file as a starting point, they will end up with the css duplicated (doesn't break things but is not good) unless they also borrow that part of the webpack config.

It's reasonable to assume that images would then be placed next to the css file, resulting in those being duplicated as well.

The sooner the CLI and skeletons are aligned the better i think. It would be great if the CLI generated a more complete project structure and webpack config as a good starting point.

I have a repo that i will be updating soon with the results of my efforts to create a nice project structure and webpack config which is documented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants