-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
Generate build without hashed file names. #821
Comments
This is not supported and it’s unlikely we would support it. Generating hashes is the right default for a vast majority of cases. If for some reason you’d rather not have them generated, you would need to maintain your own Webpack config. As an alternative to ejecting, you can fork |
Thank you. I wasn't expecting you to add it. Just wanted to know if perhaps it was supported. Thanks for the suggestions. I'll look into it. |
A different way to handle this is to do a rename as a part of your build process with a new npm run script so you don't have to do an eject. I used the
Then in
then you can modify your build script to do the rename post-build like this:
Anyways, this is just one way to do it. You will give up source maps unless you do a search and replace inside the js file, but in your specific case of putting on a mobile device that probably doesn't matter. |
Note that this will break code splitting (i.e |
Having changing hashes makes working in Visual Studio projects a bit annoying as you can't just update the files, you have to add the new ones and delete the old ones from the project file. Previously I dealt with cache busting on the chunk files like this in my webpack.config: output: {
filename: 'main.js',
chunkFilename: 'main.[id].js?v=[hash]',
}, Then in my HTML template I would add a cache busting query string like so: So adding an option to CRA to support something like this seems like a reasonably common use case. |
Based on @jrzerr workaround, I added the replace inside the js and css file to get source maps working. For the change of the sourcemap url I used replace. I use this on a windows machine:
|
@StefanSchoof 👍 |
@marcoc1712 Thanks for pointing this out. In my setup I embed js in a bigger site and have no need for these files. |
@gaearon what's your suggestion on using hashed file names together with cached CDNs? I'm using S3 to store the app and CloudFront as a CDN. When I deploy a new version, the files with old hashes are removed and new files are added. However, since CloudFront caches index.html, it points to old non-existent files until it refreshes the cache. Thus, I'm breaking the website with each build, and even if I manually refresh the cache, the website still might be down for some time until the cache is refreshed. I could store all prior versions on S3 instead of deleting them, but that doesn't seem like a good long-term solution either. |
@olgeorge did you solve this? |
I am using CRA for server side rendering along with Airbnb Hypernova. Because my backend server is not in NodeJS and I need to point to the css file from my backend APP. It is very annoying to keep updating the css paths, therefore, file without hashes should be supported. |
Here's what i did: <script type="text/javascript">
var bundle_name = "bundle.js"; // dev mode
$.getJSON("/asset-manifest.json", function(json){ var bundle_name = json["main.js"]; })
.always(function(){
var bundle = document.createElement('script');
bundle.setAttribute('type', "text/javascript");
bundle.setAttribute('src', "/static/js/" + bundle_name);
document.body.appendChild(bundle);
});
</script> |
@Sofianio that solution helped you? I couldnt do that work! :( |
I came up with a shell script which I execute instead of just Place it in your site root to make it work. In my case the destination is #!/bin/bash
yarn build
cp -v build/static/js/main.*.js ../../../public/js/main.js
cp -v build/static/css/main.*.css ../../../public/css/main.css |
@lisandrolan yes it worked for me. @aftabnaveed your solution is good but it has a downside, if you make an update, the client might not receive it because of browser cache (if file name didn't change ... the browser uses cache) |
$ yarn build /# replace hash contents /# rename hashed files inside build/static DONE |
"build": "react-scripts build && yarn run build-dist", |
@taggartj your solution looks great. |
Because someone might find this useful... I opted to do this in the application layer at startup so that I'm not affecting load time. I'm using django, but this could apply to anyone using another application layer (like rails) to serve their react app. I simply added the following to my settings.py: REACT_BUILD_DIR = os.path.join(BASE_DIR, 'frontend', 'build')
# Pull the js and css filenames from the current build
path = os.path.join(REACT_BUILD_DIR, "asset-manifest.json")
with open(path) as f:
data = json.load(f)
REACT_CSS_PATH = data['main.css'].replace('static/', '')
REACT_JS_PATH = data['main.js'].replace('static/', '') I then simply pass REACT_CSS_PATH and REACT_JS_PATH to the template that renders the react app. |
In case someone finds this helpful... Built a component mycomponent that is completely detached from the main application, even styled on it's own with emotionjs so no CSS, so I just created a file #!/bin/sh
# copy files | https://tosbourn.com/copy-rename-multiple-files-linux/
for i in ./build/static/js/main.*; do cp $i `echo $i | sed "s/main.*.js/mycomponent.js/g"`; done
# update sourcemap | sed osx backup - https://stackoverflow.com/a/25486705/1072776
sed -i "" -e "s/sourceMappingURL=main.*.js/sourceMappingURL=mycomponent.js/g"
./build/static/js/mycomponent.js Now to fire it automatically after build, i add this to {
"scripts": {
// ... create react app stuff
"postbuild": "./postbuild.sh"
}
} |
I accomplished this with a Groovy language script. But, I wonder if react-app-rewired could be used to accomplish this rename and fix of map references. |
As some of the solutions above were a bit outdated and incomplete, I came up with these scripts for package.json in case anyone finds them useful: {
"build": "react-scripts build && npm run build-rename",
"build-rename": "npm run build-rename-js && npm run build-rename-css && npm run build-fix-references",
"build-rename-js": "renamer --find \"/main\\.[^\\.]+\\./i\" --replace \"main.\" build\\static\\js\\*",
"build-rename-css": "renamer --find \"/main\\.[^\\.]+\\./i\" --replace \"main.\" build\\static\\css\\*",
"build-fix-references": "npm run build-fix-sourcemap && npm run build-fix-index && npm run build-fix-serviceworker && npm run build-fix-assetmanifest",
"build-fix-sourcemap": "npm run build-fix-sourcemap-js && npm run build-fix-sourcemap-css",
"build-fix-sourcemap-js": "replace-in-file \"/sourceMappingURL=main\\.[^\\.]+\\.js\\.map/i\" \"sourceMappingURL=main.js.map\" build/static/js/main.js --isRegex",
"build-fix-sourcemap-css": "replace-in-file \"/sourceMappingURL=main\\.[^\\.]+\\.css\\.map/i\" \"sourceMappingURL=main.css.map\" build/static/css/main.css --isRegex",
"build-fix-index": "npm run build-fix-index-js && npm run build-fix-index-css",
"build-fix-index-js": "replace-in-file \"/main\\.[^\\.]+\\.js/i\" \"main.js?v=%npm_package_version%\" build/index.html --isRegex",
"build-fix-index-css": "replace-in-file \"/main\\.[^\\.]+\\.css/i\" \"main.css?v=%npm_package_version%\" build/index.html --isRegex",
"build-fix-serviceworker": "npm run build-fix-serviceworker-js && npm run build-fix-serviceworker-css",
"build-fix-serviceworker-js": "replace-in-file \"/main\\.[^\\.]+\\.js/i\" \"main.js\" build/service-worker.js --isRegex",
"build-fix-serviceworker-css": "replace-in-file \"/main\\.[^\\.]+\\.css/i\" \"main.css\" build/service-worker.js --isRegex",
"build-fix-assetmanifest": "npm run build-fix-assetmanifest-js && npm run build-fix-assetmanifest-css && npm run build-fix-assetmanifest-js-map && npm run build-fix-assetmanifest-css-map",
"build-fix-assetmanifest-js": "replace-in-file \"/main\\.[^\\.]+\\.js/i\" \"main.js\" build/asset-manifest.json --isRegex",
"build-fix-assetmanifest-css": "replace-in-file \"/main\\.[^\\.]+\\.css/i\" \"main.css\" build/asset-manifest.json --isRegex",
"build-fix-assetmanifest-js-map": "replace-in-file \"/main\\.[^\\.]+\\.js\\.map/i\" \"main.js.map\" build/asset-manifest.json --isRegex",
"build-fix-assetmanifest-css-map": "replace-in-file \"/main\\.[^\\.]+\\.css\\.map/i\" \"main.css.map\" build/asset-manifest.json --isRegex"
} Also, don't forget to run
|
@raizenpk would one need to run all those commands to have a clean build? |
I work on the plugin which allows user to change styles of the component. Meaning that they can choose what was build with react-create-app or change styles of SCSS file and rebuild new CSS so here is what I came-up with (maybe will be useful for someone): $staticFolder = '/path/to/static/media/';
$assets = $staticFolder . '*.*';
$fileAssetList = glob( $assets );
if ( ! empty( $fileAssetList ) ) {
foreach ( $fileAssetList as $key => $assetFullPath ) {
preg_match( '/\/media\/(.*)\.[a-z0-9]+\.(svg|png|jpg|jpeg|ico|gif)$/m', $assetFullPath, $matches );
if ( count( $matches ) !== 3 ) {
continue;
}
$fullMatchAndUrl = '/path/to/static' . $matches[0];
$fileName = $matches[1];
$extension = $matches[2];
$pattern = "/\.\.\/img\/?([\w-_]*\/)$fileName\.$extension/m";
if ( preg_match( $pattern, $compiled ) ) {
$compiled = preg_replace( $pattern, $fullMatchAndUrl, $compiled );
}
}
} |
Hi all,
I'm trying this project out to simplify work on a web app that's to be embedded into a hardware device. For reasons I have no control over, the "embed" team is requesting I commit builds without hashed names. Is there a way to disable hashed names completely for the build without having to eject? This is the only thing I need to override and ejecting for that one reason seems excessive.
In case it matters, I also don't need to distribute sourcemap files in the build.
I'm happy to contribute to the docs if there is a way to do this.
Thank you,
The text was updated successfully, but these errors were encountered: