乐趣区

creatreactapp3-配置文件分析2

文件结构分析


env.js

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.  Variable expansion is supported in .env files.
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand

// 注释其实写的很清楚,用 dotenv 和 dotenv-expand 工具读取所有.env* 文件,获取变量
dotenvFiles.forEach(dotenvFile => {if (fs.existsSync(dotenvFile)) {require('dotenv-expand')(require('dotenv').config({path: dotenvFile,})
    );
  }
});
// 最后赋值给 process.env 对象
// Stringify all values so we can feed into Webpack DefinePlugin
  const stringified = {'process.env': Object.keys(raw).reduce((env, key) => {env[key] = JSON.stringify(raw[key]);
      return env;
    }, {}),
  };

modules.js
其实就两个函数,为了读取 jsconfig.json 或者 tsconfig.json 文件中的配置,两个文件不能同时存在.


paths.js 文件前面说过了


pnpTs.js 这块确实不太清楚,不敢乱讲。看内容是关于 typescript 的,有 ts-pnp 插件配置,有大神帮忙解答下。


webpack.config.js
所有 webpack 基础配置 (除了 devServer) 都在这里面了


暴露一个函数接口,参数就是环境变量

module.exports = function(webpackEnv) {
  const isEnvDevelopment = webpackEnv === 'development';
  const isEnvProduction = webpackEnv === 'production';
  ...
}

通过 ’development’ 或者 ’production’ 去加载不同的配置,

return {
    mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
    bail: isEnvProduction,
    devtool: isEnvProduction
      ? shouldUseSourceMap
        ? 'source-map'
        : false
      : isEnvDevelopment && 'cheap-module-source-map',
    entry: [
      isEnvDevelopment &&
        require.resolve('react-dev-utils/webpackHotDevClient'),
      paths.appIndexJs,
    ].filter(Boolean),
    output: {
      path: isEnvProduction ? paths.appBuild : undefined,
      pathinfo: isEnvDevelopment,
      filename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].js'
        : isEnvDevelopment && 'static/js/bundle.js',
      
      
      futureEmitAssets: true,
     
      chunkFilename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].chunk.js'
        : isEnvDevelopment && 'static/js/[name].chunk.js',
     
      publicPath: publicPath,
     
      devtoolModuleFilenameTemplate: isEnvProduction
        ? info =>
            path
              .relative(paths.appSrc, info.absoluteResourcePath)
              .replace(/\\/g, '/')
        : isEnvDevelopment &&
          (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
    },
    optimization: {
      minimize: isEnvProduction,
      minimizer: [
      
        new TerserPlugin({
          terserOptions: {
            parse: {ecma: 8,},
            compress: {
              ecma: 5,
              warnings: false,
              inline: 2,
            },
            mangle: {safari10: true,},
            output: {
              ecma: 5,
              comments: false,
              ascii_only: true,
            },
          },
          parallel: !isWsl,
          cache: true,
          sourceMap: shouldUseSourceMap,
        }),
        new OptimizeCSSAssetsPlugin({
          cssProcessorOptions: {
            parser: safePostCssParser,
            map: shouldUseSourceMap
              ? {
                  inline: false,
                  annotation: true,
                }
              : false,
          },
        }),
      ],
      splitChunks: {
        chunks: 'all',
        name: false,
      },
      runtimeChunk: true,
    },
    resolve: {modules: ['node_modules', paths.appNodeModules].concat(modules.additionalModulePaths || []
      ),
      extensions: paths.moduleFileExtensions
        .map(ext => `.${ext}`)
        .filter(ext => useTypeScript || !ext.includes('ts')),
      alias: {'react-native': 'react-native-web',},
      plugins: [PnpWebpackPlugin,],
    },
    resolveLoader: {
      plugins: [PnpWebpackPlugin.moduleLoader(module),
      ],
    },
    module: {
      strictExportPresence: true,
      rules: [{ parser: { requireEnsure: false} },
        {test: /\.(js|mjs|jsx|ts|tsx)$/,
          enforce: 'pre',
          use: [
            {
              options: {formatter: require.resolve('react-dev-utils/eslintFormatter'),
                eslintPath: require.resolve('eslint'),
                
              },
              loader: require.resolve('eslint-loader'),
            },
          ],
          include: paths.appSrc,
        },
        {
         
          oneOf: [
            {test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
              loader: require.resolve('url-loader'),
              options: {
                limit: 10000,
                name: 'static/media/[name].[hash:8].[ext]',
              },
            },
            {test: /\.(js|mjs|jsx|ts|tsx)$/,
              include: paths.appSrc,
              loader: require.resolve('babel-loader'),
              options: {
                customize: require.resolve('babel-preset-react-app/webpack-overrides'),
                
                plugins: [
                  [require.resolve('babel-plugin-named-asset-import'),
                    {
                      loaderMap: {
                        svg: {ReactComponent: '@svgr/webpack?-svgo,+ref![path]',
                        },
                      },
                    },
                  ],
                ],
                cacheDirectory: true,
                cacheCompression: isEnvProduction,
                compact: isEnvProduction,
              },
            },
           
            {test: /\.(js|mjs)$/,
              exclude: /@babel(?:\/|\\{1,2})runtime/,
              loader: require.resolve('babel-loader'),
              options: {
                babelrc: false,
                configFile: false,
                compact: false,
                presets: [
                  [require.resolve('babel-preset-react-app/dependencies'),
                    {helpers: true},
                  ],
                ],
                cacheDirectory: true,
                cacheCompression: isEnvProduction,
                sourceMaps: false,
              },
            },
            {
              test: cssRegex,
              exclude: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
              }),
              sideEffects: true,
            },
            {
              test: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
                modules: true,
                getLocalIdent: getCSSModuleLocalIdent,
              }),
            },
            
            {
              test: sassRegex,
              exclude: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                },
                'sass-loader'
              ),
            
              sideEffects: true,
            },
            
            {
              test: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  modules: true,
                  getLocalIdent: getCSSModuleLocalIdent,
                },
                'sass-loader'
              ),
            },
            
            {loader: require.resolve('file-loader'),
              
              exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
              options: {name: 'static/media/[name].[hash:8].[ext]',
              },
            },
          ],
        },
      ],
    },
    plugins: [new HtmlWebpackPlugin(),
        ...
    ]
}

webpackDevServer.config.js
devServer 的配置文件,暴露一个函数

const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const host = process.env.HOST || '0.0.0.0';

module.exports = function(proxy, allowedHost) {
    // 参数 proxy 代理配置和 allowedHost 
    return {
        ...
        contentBase: paths.appPublic,//public 文件夹路径
        publicPath: '/',
        hot: true,
        https: protocol === 'https',
        host,
        public: allowedHost,
        proxy,
        before(app,server){...}
    }
};

退出移动版