I recently created a project using create-react-app, but needed to change the /static folder name because the /static route at the back end was occupied

Failure to try

I thought I could make folder changes with fewer configuration code changes, but I tried several but failed

  1. At first I wanted to use the mv command directly, but when I saw the static resource files embedded in HTML in the code, they were attached/static/xxxMusic videos don’t work.
  2. The Internet says it can be changedpackage.jsonIn thehomepageThe resulting file is just a web in the static folder, as shown below

  1. I thought about whether I could change itPUBLIC_URLthisenvFind the same as in attempt 2, except that the static resources folder is preceded by aweb.

Eject code, analyze the problem

Thinking of the eject code, first find a new CRA project, run the eject command, and find the WebPack configuration.

Static/XXX = static/ XXX = static/ XXX

output: {
      filename: isEnvProduction
        ? 'static/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'
        : isEnvDevelopment && 'static/js/[name].chunk.js'. },module: {
      strictExportPresence: true.rules: [{// "oneOf" will traverse all following loaders until one will
          // match the requirements. When no loader matches it will fall
          // back to the "file" loader at the end of the loader list.
          oneOf: [
            // TODO: Merge this config once `image/avif` is in the mime-db
            // https://github.com/jshttp/mime-db
            {
              test: [/\.avif$/].loader: require.resolve('url-loader'),
              options: {
                limit: imageInlineSizeLimit,
                mimetype: 'image/avif'.name: 'static/media/[name].[hash:8].[ext]',}},// "url" loader works like "file" loader except that it embeds assets
            // smaller than specified limit in bytes as data URLs to avoid requests.
            // A missing `test` is equivalent to a match.
            {
              test: [/\.bmp$/./\.gif$/./\.jpe?g$/./\.png$/].loader: require.resolve('url-loader'),
              options: {
                limit: imageInlineSizeLimit,
                name: 'static/media/[name].[hash:8].[ext]',}},... isEnvProduction &&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',}).Copy the code

To solve the problem

The eject command is not used to keep the source code small. You need to use CrACO to change crA configurations

Details of crACO use can be moved to CrACO

As you can see from the code you just eject, there are three things that need to be changed

  1. Filename and chunkFilename in output
  2. Mudule. Rules loader containing options.name
  3. The plugin MiniCssExtractPlugin

Based on the above three analyses, we have the following code. To be consistent with crA internally, whenProd functions provided by CRACO are used

module.exports = {
  webpack: {
    configure: (webpackConfig, { env, paths }) = > {
      // Change webpack to static -> webwebpackConfig.output = { ... webpackConfig.output, ... {filename: whenProd(() = > 'web/js/[name].[contenthash:8].chunk.js'.'web/js/[name].chunk.js'),
          chunkFilename: whenProd(() = > 'web/js/[name].[contenthash:8].chunk.js'.'web/js/[name].chunk.js'),
        },
      }

      webpackConfig.plugins = webpackConfig.plugins.map((plugin) = > {
        whenProd(() = > {
          if (plugin instanceof MiniCssExtractPlugin) {
            Object.assign(plugin.options, {
              filename: 'web/css/[name].[contenthash:8].css'.chunkFilename: 'web/css/[name].[contenthash:8].chunk.css',})}})return plugin
      })

      webpackConfig.module.rules = webpackConfig.module.rules.map((rule) = > {
        if (rule.oneOf) {
          rule.oneOf = rule.oneOf.map((oneOfRule) = > {
            if (oneOfRule.options && oneOfRule.options.name) {
              oneOfRule.options.name = 'web/media/[name].[hash:8].[ext]';
            }
            return oneOfRule;
          });
        }
        return rule
      })

      returnwebpackConfig; }}};Copy the code

The function must finally return webPackConfig!!

Inspiration website, information

Blog.actorsfit.com/a?ID=00001-…