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

How do I build js and css without random number? #1005

Closed
noppanit opened this issue Nov 3, 2016 · 18 comments
Closed

How do I build js and css without random number? #1005

noppanit opened this issue Nov 3, 2016 · 18 comments

Comments

@noppanit
Copy link

noppanit commented Nov 3, 2016

Is there a way I can build production css and js file without the random generated number at the file?

For example, every time I build I get something like this main.a31171f1.css and main.a31171f1.js. I need this because I want to be able to fix that in my index.html.

Thanks.

@tbillington
Copy link

You can see here for what it is and why it is useful https://webpack.github.io/docs/long-term-caching.html.

You could edit your build script to run a shell script afterwards and rename them.

@thien-do
Copy link
Contributor

thien-do commented Nov 3, 2016

Yes, I'm not sure why you need to remove those "random generated number" (also, it is not random, it is a hash based on your file content, which is, as @tbillington explained, useful for caching)

Beside tbillington's solution, you can also eject or fork CRA and make your change in the config file (like this line is what cause the hash in the name of CSS file). Althought, I think tbillington's solution is best for this case.

@noppanit
Copy link
Author

noppanit commented Nov 3, 2016

Thanks, the reason is that because we use DFP and it takes about 15 min for DFP to change the HTML. So, we just upload the main.js and main.css to S3 and serve from there instead. Thanks for the suggestion I'll eject CRA and do that.

@noppanit noppanit closed this as completed Nov 3, 2016
@tbillington
Copy link

@noppanit Just for posterity, my build looks like this

"build": "react-scripts build && npm run build:clean",
"build:clean": "cd build && mv static/js/*.js main.js && mv static/css/*.css main.css && rm -r static",

@noppanit
Copy link
Author

noppanit commented Nov 4, 2016

@tbillington Thanks! that's exactly what I ended doing.

@gaearon
Copy link
Contributor

gaearon commented Nov 4, 2016

Instead of removing hashes and thus potentially breaking your website for people who have cached some of the files but not the others, could you merge the old and new build folders? Since the hashes are based on content, you won't have name clashes. Keep old files together with new files for a single deploy, then do the same for the next deploy. And you don't need to eject; just add your custom script to scripts section in package.json.

  "deploy": "node scripts/my-custom-deploy-script.js"

@noppanit
Copy link
Author

noppanit commented Nov 5, 2016

Thanks a lot! I'll try that.

@valle-xyz
Copy link

Just wanted to salt this discussion with my hash: I also need some hash-less filenames, because I digest the static files with Phoenix, which does the hashing itself. The asset-manifest doesn't work here, so maybe you should reconsider a option for hash-less filesnames.

Renaming is a workaround, but ... does CRA support Chunks? If yes, renaming would be painful.

@thien-do
Copy link
Contributor

thien-do commented Nov 6, 2016

@Valentin-Seehausen: is this what you mean by "chunks"?

@valle-xyz
Copy link

Jap, code splitting. Ok, so CRA supports it secretly? :)

-> So renaming is not a long-term solution. How do I handle this hashing issue?

@lasergoat
Copy link

@tbillington @dvkndn @Valentin-Seehausen @gaearon

Hey guys, I hate to dig up the past, but...

There is some validity to needing to remove the content hashes, or at least have access to what they are after each file change. I've been making some chrome extensions with r-c-a and the only way I've found to include my scripts into my manifest.json is to either:

  1. edit the hashes each time - obvs wouldn't do that
  2. use another script to either find the hashes from the lfs and put them into my manifest.json
  3. npm run eject and modify the build script to not use hashes (that's what I've been doing)

This way, my chrome extension can simply do:

  chrome.tabs.executeScript(tab.ib, {
    file: 'static/js/main.js'
    // instead of 'static/js/main.[unknown hash].js'
  });

  chrome.tabs.insertCSS(tab.id, {
    file: 'static/css/main.css'
  });

But now, I'm interested in adding an option to r-c-a to not append content hashes.

The other solution is to calculate the hashes on my own and modify my manifest.json file on each file change - but I'd need a parallel process with my own watch to do that when using npm start (because I'd like to avoind running npm run build each time I make a change. With chrome extensions, hashes have far less value from a web app since you have to reload your extension in chrome anyways on each file change. So right now, option 3 is still my best bet - but I don't like ejecting there's no real reason I've found to do so other than this.

@danieldram
Copy link

One way I got around dealing with this issue and putting the output where I want is to just
mv -f src/file-hash.js dest/file-what-i-want
in my npm scripts after the build. I don't know if this is the best way, but It seems to work for me and just a quick hacky suggestion

@gaearon
Copy link
Contributor

gaearon commented Mar 6, 2017

When you run build, a file called asset-manifest.json (if I recall correctly) appears in the build folder. It contains the list of all files. You can read it in a post build step and then do anything you like (such as use that info for rewriting Chrome extension manifest).

Hope this helps.

@lasergoat
Copy link

@gaearon @danieldram thanks for the quick replies!

For using the asset-manifest, I would still need to set a watch on it if I intend to use r-c-a npm start right?

What I'm saying is, when I edit some code, and webpack runs and all my new code gets dumped into build/, I'd still need a way to trigger a change to my chrome manifest.json file - that would be that part that would read the new values in asset-manifest and use them accordingly.

@gaearon
Copy link
Contributor

gaearon commented Mar 6, 2017

The asset manifest only gets created on npm run build. There are no physical files created during npm start anyway, so there is nothing to copy. For a watching mode that writes to disk in development, please track #1070.

@viankakrisna
Copy link
Contributor

@lasergoat you might be interested in #4014

@agm1984
Copy link

agm1984 commented Mar 24, 2018

Using Mr. Abramov's mention of asset-manifest.json, I created this script a person could run if they use node.js:

const fs = require('fs');

// Put manifest.json contents into an Object
let manifest = JSON.parse(fs.readFileSync('build/manifest.json', 'utf8'));

// Get hashes from asset-manifest.json
const hashes = JSON.parse(fs.readFileSync('build/asset-manifest.json', 'utf8'));

// Update manifest with extracted hashes
manifest.content_scripts[0].css[0] = hashes['main.css'];
manifest.content_scripts[0].js[0] = hashes['main.js'];

// Write updated manifest.json
fs.writeFileSync('build/manifest.json', JSON.stringify(manifest, null, 2));

@NateAGeek
Copy link

NateAGeek commented Jul 20, 2018

Something that I was able to do with React Rewired (https://github.com/timarney/react-app-rewired). I will say that if you are really overriding a lot in the future it might be worth ejecting.

// config-overrides.js
module.exports = {
  webpack: function(config, env) {
    if (env === "production") {
      //JS Overrides
      config.output.filename = 'static/js/[name].js';
      config.output.chunkFilename = 'static/js/[name].chunk.js';

      //CSS Overrides
      config.plugins[4].filename = 'static/css/[name].css';

      //Media and Assets Overrides
      config.module.rules[1].oneOf[0].options.name = 'static/media/[name].[ext]';
      config.module.rules[1].oneOf[3].options.name = 'static/media/[name].[ext]';
    }

    return config;
  }
};

This should take care of the hashes, mapping, and media/asset. Sadly with the way plugins are implemented in an array, I have to use fixed indexes. Also, if you do end up adding more plugins it could mess with those fixed indexes.

@lock lock bot locked and limited conversation to collaborators Jan 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants