Skip to content

Generate build without hashed file names. #821

Closed

Description

@lgomez

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,

Activity

  1. gaearon commented on Oct 2, 2016

    @gaearon
    Contributor

    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 react-scripts: #779.

  2. lgomez commented on Oct 2, 2016

    @lgomez
    Author

    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.

  3. jrzerr commented on Jun 7, 2017

    @jrzerr

    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 renamer npm library to do this for me.

    npm install --save-dev renamer
    

    Then in package.json scripts section I added some rename helpers:

        "build-rename": "npm run build-rename-js && npm run build-rename-css",
        "build-rename-js": "renamer --regex --find 'main\\.[^\\.]+\\.js' --replace 'main.js' build/static/js/*.js",
        "build-rename-css": "renamer --regex --find 'main\\.[^\\.]+\\.css' --replace 'main.css' build/static/css/*.css",
    

    then you can modify your build script to do the rename post-build like this:

    "build": "react-scripts build && npm run build-rename",
    

    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.

  4. gaearon commented on Jun 7, 2017

    @gaearon
    Contributor

    Note that this will break code splitting (i.e import('./module').then(...)) because the hardcoded JS path in the bundle will be wrong.

  5. StefanSchoof commented on Nov 30, 2017

    @StefanSchoof

    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:

    "scripts": {
        ...
        "build": "react-scripts-ts build&&npm run build-rename",
        "build-rename": "npm run build-rename-js&&npm run build-rename-css&&npm run build-fix-sourcemap",
        "build-rename-js": "renamer --regex --find \"main\\.[^\\.]+\\.\" --replace \"main.\" build\\static\\js\\*",
        "build-rename-css": "renamer --regex --find \"main\\.[^\\.]+\\.\" --replace \"main.\" build\\static\\css\\*",
        "build-fix-sourcemap": "npm run build-fix-sourcemap-js&&npm run build-fix-sourcemap-css",
        "build-fix-sourcemap-js": "replace \"# sourceMappingURL=main..*.js.map\" \"# sourceMappingURL=main.js.map\" build\\static\\js\\main.js",
        "build-fix-sourcemap-css": "replace \"# sourceMappingURL=main..*.map\" \"# sourceMappingURL=main.css.map\" build\\static\\css\\main.css"
      },
    
  6. marcoc1712 commented on Dec 10, 2017

    @marcoc1712

    @StefanSchoof 👍
    It works, but you should replace css and js also in index.html and service-worker.js in the main directory.

  7. StefanSchoof commented on Dec 14, 2017

    @StefanSchoof

    @marcoc1712 Thanks for pointing this out. In my setup I embed js in a bigger site and have no need for these files.

  8. olgeorge commented on Dec 21, 2017

    @olgeorge

    @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.

  9. Meemaw commented on Mar 20, 2018

    @Meemaw

    @olgeorge did you solve this?

  10. aftabnaveed commented on Mar 26, 2018

    @aftabnaveed

    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.

  11. Sofianio commented on Mar 26, 2018

    @Sofianio

    Here's what i did:
    in the file index.html
    I get the bundle name from asset-manifest.json
    then add the script with the bundle name

    <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>
  12. lisandrolan commented on Apr 4, 2018

    @lisandrolan

    @Sofianio that solution helped you? I couldnt do that work! :(

  13. aftabnaveed commented on Apr 10, 2018

    @aftabnaveed

    I came up with a shell script which I execute instead of just yarn build

    Place it in your site root to make it work. In my case the destination is ../../../public/js/main.js you may change it your desired destination.

    #!/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
  14. Sofianio commented on Apr 10, 2018

    @Sofianio

    @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)
    ... there's a reason why they add random numbers to the file name

  15. chunhui2001 commented on Apr 27, 2018

    @chunhui2001

    $ yarn build

    /# replace hash contents
    /# get hash definition in build/asset-manifest.json and replace hashed contents using awk and sed
    $ cat build/asset-manifest.json | grep -o -E "\.[0-9a-z]{8}\." |
    awk '{system("find ./build/static -exec sed -i \"\" -E \"s/\\" $0 "/./g\" {} \\; 2>/dev/null")}'

    /# rename hashed files inside build/static
    $ find ./build/static -type f | grep -E "\.[0-9a-z]{8}\." | rename "s/.[a-z0-9]{8}././g"

    DONE

  16. taggartj commented on Jul 3, 2018

    @taggartj

    "build": "react-scripts build && yarn run build-dist",
    "build-dist": "cd build && cp static/js/.js main.js && cp static/css/.css main.css"

  17. Kopatch commented on Jul 4, 2018

    @Kopatch

    @taggartj your solution looks great.
    Just want to add to solution - for Windows users use
    "build-dist": "cd build && copy static\\js\\*.js main.js && copy static\\css\\*.css main.css"

  18. jamstooks commented on Jul 24, 2018

    @jamstooks

    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.

  19. jubalm commented on Aug 27, 2018

    @jubalm

    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 postbuild.sh and set it's permission chmod +x postbuild.sh

    #!/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 package.json

    {
      "scripts": {
        // ... create react app stuff
        "postbuild": "./postbuild.sh"
      }
    }
  20. josefbetancourt commented on Sep 2, 2018

    @josefbetancourt

    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.

  21. essar05 commented on Sep 12, 2018

    @essar05

    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

    npm i --save-dev renamer
    npm i --save-dev replace-in-file
    
  22. reactiongears commented on Nov 15, 2018

    @reactiongears

    @raizenpk would one need to run all those commands to have a clean build?

  23. bologer commented on Nov 17, 2018

    @bologer

    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 );
    		}
    	}
    }
  24. locked and limited conversation to collaborators on Jan 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions