6

I have a React project on which I ran npm run build and it made a production build for me. The problem is that it gives me the following stylesheet injected into the index.html

<script src="./static/js/5.a4bfdba9.chunk.js"></script>

As you can see, the path set is ./static/js/

But I want the path to be set to ./static/dashboard/js/5.a4bfdba9.chunk.js

I can't figure out where or what to change to ensure every time I run the build, it takes the path specified by me instead of the default path?

Note: I looked at "homepage": "." attribute in package.json but changing this will only append a path before /static/js/

5
  • Which utility did you use to start the project? Create react app? Are you using typescript or just JavaScript? Commented Mar 16, 2021 at 12:17
  • @JensBodal I use create react app Commented Mar 16, 2021 at 12:19
  • Are you using typescript? Commented Mar 16, 2021 at 12:20
  • @JensBodal No it's a simple react project. Commented Mar 16, 2021 at 12:23
  • Does this answer your question? Use custom build output folder when using create-react-app Commented May 4, 2022 at 14:39

4 Answers 4

15

Today there is a better solution. From hashrocket:

When I build my CRA app I get a path for my assets (css, images) that begins with /static. If I deploy my app to https://something.com/myapp, then the app will try to access those asset paths at https://something.com/static/asset.css. That's not where the asset lives. The asset lives at https://something.com/myapp/static/asset.css.

Create React App allows you to change the prefix for a the built assets with the homepage attribute in your package.json file.

You could set it to myapp:

"homepage": "/myapp"

And then the asset will have the path of /myapp/static/asset.css


In my case, I made the following changes to my package.json:

  "homepage": "/search",
  "build": "react-scripts build && mkdir build/search && mv build/static build/search/static"

This is because I had an nginx reverse proxy serving /search to a different endpoint, so all my static assets had to be served from /search/static instead.

Sign up to request clarification or add additional context in comments.

2 Comments

happy to hear it!
Thanks for linking hashrocket. It really help me though it does not fixed my issue but gave me some clarity. Kudos!! :)
8

Update:

You will need to update the webpack config to achieve this. There are multiple ways to do that:

  1. react-scripts eject (not recommended)
  2. patch-package
  3. react-app-rewired

I am providing steps for patch-package.
You need to make changes to the file config/webpack.config.js of react-scripts package. Here is a git diff of changes you need to make:

diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
index 26c2a65..ad29fbd 100644
--- a/node_modules/react-scripts/config/webpack.config.js
+++ b/node_modules/react-scripts/config/webpack.config.js
@@ -212,13 +212,13 @@ module.exports = function (webpackEnv) {
       // There will be one main bundle, and one file per asynchronous chunk.
       // In development, it does not produce real files.
       filename: isEnvProduction
-        ? 'static/js/[name].[contenthash:8].js'
+        ? 'static/dashboard/js/[name].[contenthash:8].js'
         : isEnvDevelopment && 'static/js/bundle.js',
       // TODO: remove this when upgrading to webpack 5
       futureEmitAssets: true,
       // There are also additional JS chunk files if you use code splitting.
       chunkFilename: isEnvProduction
-        ? 'static/js/[name].[contenthash:8].chunk.js'
+        ? 'static/dashboard/js/[name].[contenthash:8].chunk.js'
         : isEnvDevelopment && 'static/js/[name].chunk.js',
       // webpack uses `publicPath` to determine where the app is being served from.
       // It requires a trailing slash, or the file assets will get an incorrect path.
@@ -676,8 +676,8 @@ module.exports = function (webpackEnv) {
         new MiniCssExtractPlugin({
           // Options similar to the same options in webpackOptions.output
           // both options are optional
-          filename: 'static/css/[name].[contenthash:8].css',
-          chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
+          filename: 'static/dashboard/css/[name].[contenthash:8].css',
+          chunkFilename: 'static/dashboard/css/[name].[contenthash:8].chunk.css',
         }),
       // Generate an asset manifest file with the following content:
       // - "files" key: Mapping of all asset filenames to their corresponding

Now if you make these changes to node_modules/react-scripts/config/webpack.config.js you will get the files outputted to your desired folder and index.html will have correct paths too.
But the changes in node_modules will be overwritten if you install/uninstall any package. To persist those changes you can use patch-package, which will write your changes in node_modules after install.

Here are the steps to setup patch-package, you can read their readme file for more details:

  1. yarn add patch-package postinstall-postinstall

  2. Add this in scripts section of package.json:
    "postinstall": "patch-package"

  3. run patch-package to create a .patch file:
    npx patch-package some-package

  4. commit the patch file to share the fix with your team
    git add patches/react-scripts+4.0.3.patch
    git commit -m "change output dir structure in react-scripts"

I have created a git repository too for your reference.

Old Answer:

Warning: won't work for moving contents of build folder. Can move the whole build folder only. eg: mv build/ dist/

Changing settings of create react app so that it outputs to different folder will be very complicated. But you can move the files after build completes, which is much simple.

In your package.json you have:

"scripts": {
  "build": "react-scripts build"

You can add another script called postbuild that does something after the build and will be called by npm/Yarn automatically.

"postbuild": "mv build/ dist/"

This should move the files to different folder.

2 Comments

Thanks for your answer but I had to do a little modification to the post build command. I had to create the dashboard folder first. So my final command was "postbuild": "mkdir build/static/dashboard && mv build/static/js/ build/static/dashboard/js/ && mv build/static/css/ build/static/dashboard/css/" You may update your answer for the benefit of future readers. Thanks for pointing me to the right direction.
Hey I can see that its creating the css and js folders under the dashboard folder but in the index.html, it still refers to the path ./static/js/5.a4bfdba9.chunk.js. Do I need to change anything else?
0
  1. Run yarn add @craco/craco
  2. Create craco.config.js file
  3. Add to craco.config.js file:
module.exports = {
    webpack: {
        configure: (webpackConfig) => {
            webpackConfig.output.chunkFilename = `${staticFileName}/js/[name].[contenthash].chunk.js`;
            webpackConfig.output.filename = `${staticFileName}/js/[name].[contenthash].js`;
            webpackConfig.output.assetModuleFilename = `${staticFileName}/media/[name].[hash][ext]`;

            // MiniCssExtractPlugin içinde CSS yollarını güncelle
            webpackConfig.plugins.forEach((plugin) => {
                if (plugin instanceof MiniCssExtractPlugin) {
                    plugin.options.filename = `${staticFileName}/css/[name].[contenthash].css`;
                    plugin.options.chunkFilename = `${staticFileName}/css/[name].[contenthash].chunk.css`;
                }
            });

            return webpackConfig;
        },
    },
};

Comments

-3

In case anyone else runs into a similar problem. My issue was that the project name was being prepended to the static path.

So the path was /{project-name}/static/5.a4bfdba9.chunk.js instead of /static/5.a4bfdba9.chunk.js

Following the solution provided I came across a note specifying the "public path" was inferred from homepage. In the package.json my homepage url included the project name.

Wrong "homepage": "https://{URL}.io/project-name"

Correct "homepage": "https://{URL}.io/project-name"

Removing the project name from this url resolved the issue.

1 Comment

your wrong and correct are the same url.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.