欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

create-react-app項目配置全解析

 更新時間:2022年06月24日 15:09:36   作者:喵__40c2  
這篇文章主要為大家介紹了create-react-app項目配置全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

create-react-app(以下簡稱cra)作為react官方提供的腳手架工具,是目前生成react項目一個非常常用和主流的工具。很多企業(yè)級的應(yīng)用搭建也是基于這個腳手架工具上二次開發(fā)。最近這段正好最近學(xué)習(xí)了webpack打包配置工程化的一些內(nèi)容,索性就以cra的配置為例,對這段時間的學(xué)習(xí)做一個總結(jié)。

準備工作

首先,我們要用cra創(chuàng)建一個項目。這個沒啥好說,有手就行。

create-react-app cra-config-project

這樣初始化后創(chuàng)建出來項目的配置信息是隱藏在node_modules中的react-scripts中的。為了更直觀的看到配置信息和修改,使用
eject命令將配置彈射出來。

yarn eject

完成后,我們項目配置的目錄結(jié)構(gòu)變成這樣。

啟動命令

打開package.json 文件,在scripts中看到以下三條命令

  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js"
  },

很明顯,這分別是項目的啟動開發(fā)環(huán)境,構(gòu)建,測試的命令。我們重點看一下scripts中開發(fā)和構(gòu)建的腳本。

start.js

在大概115行的位置,我們看到這樣一段代碼

    const devServer = new WebpackDevServer(serverConfig, compiler);
    // Launch WebpackDevServer.
    devServer.startCallback(() => {
    ...

很明顯,這就是啟動開發(fā)服務(wù)器的關(guān)鍵代碼。在開發(fā)環(huán)境的時候,我們通過webpack-dev-server來啟動一個本地的服務(wù)器,然后把隨時構(gòu)建出來的項目放在這個服務(wù)器下面運行。實例化這個devServer對象時候傳的第一個參數(shù)是服務(wù)器的配置項,包括端口號,代理,靜態(tài)資源目錄等,具體見https://webpack.docschina.org/configuration/dev-server/;第二個參數(shù)是webpack的相關(guān)配置。如下所示:

  compiler = webpack(config);

build.js

構(gòu)建腳本直接輸出打包結(jié)果,自然不再需要啟動本地服務(wù)。因此在獲取了編譯結(jié)果后,直接運行即可。因此在140行中

 compiler.run((err, stats) => {
   //...
 }

在代碼中我們可以看到構(gòu)建時,編譯過程通過promise封裝,對各種錯誤情況進行了處理。

目錄結(jié)構(gòu)

在看具體的配置之前,讓我們回到這張圖,看一下eject命令都彈射出了哪些配置放到了項目目錄中來。

比起初使?fàn)顟B(tài),現(xiàn)在的項目目錄中除了裝有啟動腳本文件的目錄scripts外,另外增加的就是config目錄。打開config目錄,webpack.config.js和webpackDevServer.config.js赫然在目,根據(jù)這個文件名我們可以很明顯得知,這兩個文件一個是webpack的配置,一個是開發(fā)服務(wù)器devServer 的配置。接下來,我們就可以從這兩個文件按圖索驥,學(xué)習(xí)cra的基本配置了。

配置解析

weback.config.js

在webpack.config.js中,默認導(dǎo)出了一個接受一個環(huán)境變量作為返回一個配置對象的方法。那傳這個環(huán)境變量的目的不言而喻,一定有很多配置開發(fā)和生產(chǎn)環(huán)境是不同的。接下來重頭戲來了,讓我們來一條一條地學(xué)習(xí)下react官方對react開發(fā)環(huán)境是怎么配置的吧。

1.entry

 entry: paths.appIndexJs,

也就是 src目錄下的index.js,因為cra構(gòu)建的是單頁應(yīng)用,只有一個入口文件

2.output

 output: {
      path: paths.appBuild, // 打包后文件目錄 在config目錄中path.js中配置
      pathinfo: isEnvDevelopment, // webpack 在 bundle 中是否引入「所包含模塊信息」的相關(guān)注釋 開發(fā)環(huán)境打開 生產(chǎn)環(huán)境關(guān)閉
      filename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].js'
        : isEnvDevelopment && 'static/js/bundle.js',//打包后文件名,生產(chǎn)環(huán)境根據(jù)name放在不同文件,開發(fā)環(huán)境放在一個bundle.js文件中
     chunkFilename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].chunk.js'
        : isEnvDevelopment && 'static/js/[name].chunk.js',//chunk文件名稱,生產(chǎn)環(huán)境和開發(fā)環(huán)境的區(qū)別是文件名中加上了hash
      assetModuleFilename: 'static/media/[name].[hash][ext]',//打包后的靜態(tài)資源目錄和文件名規(guī)則,如不指定直接放在打包后的根目錄中
       publicPath: paths.publicUrlOrPath,//打包后的文件部署的url地址
       devtoolModuleFilenameTemplate: isEnvProduction
        ? info =>
            path
              .relative(paths.appSrc, info.absoluteResourcePath)
              .replace(/\\/g, '/')
        : isEnvDevelopment &&
          (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),//自定義source-map文件數(shù)組使用名稱
}

3.target

    target: ['browserslist'],

構(gòu)建目標,從 browserslist-config 中推斷出平臺和 ES 特性 默認是browserslist 如果browserslist不存在,為web(cra項目中browserslist在package.json中)

4.bail

    bail: isEnvProduction,

錯誤出現(xiàn)時是否立即退出,生產(chǎn)環(huán)境下打開

5.devtool

devtool: isEnvProduction
      ? shouldUseSourceMap
        ? 'source-map'
        : false
      : isEnvDevelopment && 'cheap-module-source-map',

生成sourceMap方式,cra配置為生產(chǎn)環(huán)境source-map,開發(fā)環(huán)境為cheap-module-source-map。這兩者的區(qū)別source-map調(diào)試時會顯示列信息。devtool的配置有很多種,具體見https://webpack.docschina.org/configuration/devtool/#root

6.cache

    cache: {
      type: 'filesystem',//緩存生成的 webpack 模塊和 chunk,來改善構(gòu)建速度 開發(fā)環(huán)境下默認為type:'memory' 生產(chǎn)環(huán)境下關(guān)閉
      version: createEnvironmentHash(env.raw),
      cacheDirectory: paths.appWebpackCache,//緩存目錄
      store: 'pack',
      buildDependencies: {
        defaultWebpack: ['webpack/lib/'],
        config: [__filename],
        tsconfig: [paths.appTsConfig, paths.appJsConfig].filter(f =>
          fs.existsSync(f)
        ),
      },
    },

7.optimization 優(yōu)化項

 optimization: {
      minimize: isEnvProduction, //只在生產(chǎn)環(huán)境下開啟
      minimizer: [
        //js TerserPlugin開啟代碼壓縮
        new TerserPlugin({
          terserOptions: {
            parse: {
              ecma: 8,
            },
            compress: {
              ecma: 5,
              warnings: false,
              comparisons: false,
              inline: 2,
            },
            mangle: {
              safari10: true,
            },
            keep_classnames: isEnvProductionProfile,
            keep_fnames: isEnvProductionProfile,
            output: {
              ecma: 5,
              comments: false,
              ascii_only: true,
            },
          },
        }),
       //css 代碼壓縮
        new CssMinimizerPlugin(),
      ],
    },

8.resolve 解析

resolve: {
     modules: ['node_modules', paths.appNodeModules].concat(
       modules.additionalModulePaths || []
     ),//解析模塊時應(yīng)該搜索的目錄
     extensions: paths.moduleFileExtensions
       .map(ext => `.${ext}`)
       .filter(ext => useTypeScript || !ext.includes('ts')),//如果有多個文件有相同的名字,但后綴名不同時webpack按順序解析這些后綴名,使用戶在引入模塊時不帶擴展名
     alias: {      
       'react-native': 'react-native-web',
       ...(isEnvProductionProfile && {
         'react-dom$': 'react-dom/profiling',
         'scheduler/tracing': 'scheduler/tracing-profiling',
       }),
       ...(modules.webpackAliases || {}),
     },//創(chuàng)建 import 或 require 的別名,來確保模塊引入變得更簡單??梢越outils之類的文件色之后
     plugins: [
       new ModuleScopePlugin(paths.appSrc, [
         paths.appPackageJson,
         reactRefreshRuntimeEntry,
         reactRefreshWebpackPluginRuntimeEntry,
         babelRuntimeEntry,
         babelRuntimeEntryHelpers,
         babelRuntimeRegenerator,
       ]),
     ],
   },//應(yīng)該使用的額外的解析插件列表

9.performance

performance: false,

關(guān)閉了webpack本身的性能提示,cra本身提供了FileSizeReporter來計算和報告文件大小

10. module

終于進入到我們這個比較重要的module配置項,module配置決定了webpack如何解析非js的模塊,項目中的各種靜態(tài)資源,樣式文件,乃至于ts tsx jsx等loader配置都是在這個模塊中配置。

  • source-map loader
        shouldUseSourceMap && {
          enforce: 'pre',
          exclude: /@babel(?:\/|\\{1,2})runtime/,
          test: /\.(js|mjs|jsx|ts|tsx|css)$/,
          loader: require.resolve('source-map-loader'),
        },
  • 靜態(tài)資源loader
            {
              test: [/\.avif$/],
              type: 'asset',
              mimetype: 'image/avif',
              parser: {
                dataUrlCondition: {
                  maxSize: imageInlineSizeLimit,
                },
              },
            },
            {
              test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
              type: 'asset',
              parser: {
                dataUrlCondition: {
                  maxSize: imageInlineSizeLimit,
                },
              },
            },
            {
              test: /\.svg$/,
              use: [
                {
                  loader: require.resolve('@svgr/webpack'),
                  options: {
                    prettier: false,
                    svgo: false,
                    svgoConfig: {
                      plugins: [{ removeViewBox: false }],
                    },
                    titleProp: true,
                    ref: true,
                  },
                },
                {
                  loader: require.resolve('file-loader'),
                  options: {
                    name: 'static/media/[name].[hash].[ext]',
                  },
                },
              ],
              issuer: {
                and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
              },
            },

對各種格式的圖片,svg文件的處理

  • 樣式文件loader
            {
              test: cssRegex,
              exclude: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction
                  ? shouldUseSourceMap
                  : isEnvDevelopment,
                modules: {
                  mode: 'icss',
                },
              }),
              sideEffects: true,
            },
            {
              test: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction
                  ? shouldUseSourceMap
                  : isEnvDevelopment,
                modules: {
                  mode: 'local',
                  getLocalIdent: getCSSModuleLocalIdent,
                },
              }),
            },
            {
              test: sassRegex,
              exclude: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 3,
                  sourceMap: isEnvProduction
                    ? shouldUseSourceMap
                    : isEnvDevelopment,
                  modules: {
                    mode: 'icss',
                  },
                },
                'sass-loader'
              ),
              sideEffects: true,
            },
            {
              test: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 3,
                  sourceMap: isEnvProduction
                    ? shouldUseSourceMap
                    : isEnvDevelopment,
                  modules: {
                    mode: 'local',
                    getLocalIdent: getCSSModuleLocalIdent,
                  },
                },
                'sass-loader'
              ),
            },

對樣式文件的處理, 主要是scss和css,cra 為什么沒有配置less文件loader呢?開發(fā)環(huán)境下直接將所有樣式注入head中style中,生產(chǎn)環(huán)境下結(jié)合下面要介紹的miniCssExtractPlugin插件抽出后放入不同css文件。另外,這里cra還對以.module.css 和 .module.sass后綴結(jié)尾的文件進行了css module處理,如果開發(fā)者需要對樣式文件要用modules規(guī)則,可以將文件的后綴寫成這兩種。
 

11. 插件

  • htmlWebpackPlugin
      new HtmlWebpackPlugin(
        Object.assign(
          {},
          {
            inject: true,
            template: paths.appHtml,
          },
          isEnvProduction
            ? {
                minify: {
                  removeComments: true,
                  collapseWhitespace: true,
                  removeRedundantAttributes: true,
                  useShortDoctype: true,
                  removeEmptyAttributes: true,
                  removeStyleLinkTypeAttributes: true,
                  keepClosingSlash: true,
                  minifyJS: true,
                  minifyCSS: true,
                  minifyURLs: true,
                },
              }
            : undefined
        )
      ),

沒啥好說的,地球人都知道的一個插件,把打包好的js文件注入到html中去,要注意的是在生產(chǎn)環(huán)境了開啟了移除注釋,合并空格一系列優(yōu)化配置

  • InlineChunkHtmlPlugin
 isEnvProduction &&
        shouldInlineRuntimeChunk &&
        new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),

這個插件輔助將一些chunk出來的模塊內(nèi)聯(lián)到html中,比如runtime的代碼,代碼量不大。生產(chǎn)環(huán)境下開啟

  • InterpolateHtmlPlugin
      new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),

HtmlWebpackPlugin的輔助插件,可以在html文件中加入變量

  • ModuleNotFoundPlugin
  • ReactRefreshWebpackPlugin
    isEnvDevelopment &&
        shouldUseReactRefresh &&
        new ReactRefreshWebpackPlugin({
          overlay: false,
        }),

熱更新 react 組件,開發(fā)環(huán)境下開啟

  • MiniCssExtractPlugin
 isEnvProduction &&
        new MiniCssExtractPlugin({
          filename: 'static/css/[name].[contenthash:8].css',
          chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
        }),

抽離css文件插件,生產(chǎn)環(huán)境下開啟

  • WebpackManifestPlugin
  • ForkTsCheckerWebpackPlugin
      useTypeScript &&
        new ForkTsCheckerWebpackPlugin({
          async: isEnvDevelopment,
          typescript: {
            typescriptPath: resolve.sync('typescript', {
              basedir: paths.appNodeModules,
            }),
            configOverwrite: {
              compilerOptions: {
                sourceMap: isEnvProduction
                  ? shouldUseSourceMap
                  : isEnvDevelopment,
                skipLibCheck: true,
                inlineSourceMap: false,
                declarationMap: false,
                noEmit: true,
                incremental: true,
                tsBuildInfoFile: paths.appTsBuildInfoFile,
              },
            },
            context: paths.appPath,
            diagnosticOptions: {
              syntactic: true,
            },
            mode: 'write-references',
          },
          issue: {
            include: [
              { file: '../**/src/**/*.{ts,tsx}' },
              { file: '**/src/**/*.{ts,tsx}' },
            ],
            exclude: [
              { file: '**/src/**/__tests__/**' },
              { file: '**/src/**/?(*.){spec|test}.*' },
              { file: '**/src/setupProxy.*' },
              { file: '**/src/setupTests.*' },
            ],
          },
          logger: {
            infrastructure: 'silent',
          },
        }),

強制ts類型檢查,如果項目使用了typescript編寫的話使用

  • webpack.definePlugin
      new webpack.DefinePlugin(env.stringified),

wepack內(nèi)置插件,在瀏覽器環(huán)境中定義環(huán)境變量

  • webpack.ignorePlugin
    new webpack.IgnorePlugin({
        resourceRegExp: /^\.\/locale$/,
        contextRegExp: /moment$/,
      }),

wepack內(nèi)置插件,可以在打包時有選擇的忽略一些內(nèi)容,這里的配置是在打包moment的時候忽略moment的本地化內(nèi)容

 isEnvDevelopment && new CaseSensitivePathsPlugin(),

解決為了解決mac系統(tǒng)中文件名大小寫不敏感導(dǎo)致的打包不報錯的問題,詳見https://github.com/facebook/create-react-app/issues/240

結(jié)語

對于工程化經(jīng)驗特別少的開發(fā)者來說,webpack的配置浩如煙海,宛如一本百科全書讓人望而興嘆。但是掌握webpack可以說是前端開發(fā)者進階的必經(jīng)之路。在學(xué)習(xí)的過程中,可以自己多搞一些demo,多去嘗試和實踐,就會漸漸的對它熟悉起來。之后,筆者計劃對webpack打包的性能優(yōu)化從配置項的各個維度做一個總結(jié),請拭目以待。

以上就是create-react-app項目配置全解析的詳細內(nèi)容,更多關(guān)于create-react-app項目配置的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React表單容器的通用解決方案

    React表單容器的通用解決方案

    本文主要介紹了React表單容器的通用解決方案,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • React state狀態(tài)屬性詳細講解

    React state狀態(tài)屬性詳細講解

    React將組件(component)看成一個狀態(tài)機(State Machines),通過其內(nèi)部自定義的狀態(tài)(State)和生命周期(Lifecycle)實現(xiàn)并與用戶交互,維持組件的不同狀態(tài)
    2022-09-09
  • React組件之間的通信的實例代碼

    React組件之間的通信的實例代碼

    本篇文章主要介紹了React組件間通信的實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • React中的生命周期詳解

    React中的生命周期詳解

    這篇文章主要介紹了React中的生命周期,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • React?Context原理深入理解源碼示例分析

    React?Context原理深入理解源碼示例分析

    這篇文章主要為大家介紹了React?Context原理深入理解源碼示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Remix如何支持原生?CSS方法詳解

    Remix如何支持原生?CSS方法詳解

    這篇文章主要為大家介紹了Remix如何支持原生CSS的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • 說說react中引入css的方式有哪些并區(qū)別在哪

    說說react中引入css的方式有哪些并區(qū)別在哪

    本文主要介紹了說說react中引入css的方式有哪些并區(qū)別在哪,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 在?React?中如何從狀態(tài)數(shù)組中刪除一個元素

    在?React?中如何從狀態(tài)數(shù)組中刪除一個元素

    這篇文章主要介紹了在?React?中從狀態(tài)數(shù)組中刪除一個元素,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • React組件的三種寫法總結(jié)

    React組件的三種寫法總結(jié)

    本文主要總結(jié)了React組件的三種寫法以及最佳實踐,具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • react中關(guān)于Context/Provider/Consumer傳參的使用

    react中關(guān)于Context/Provider/Consumer傳參的使用

    這篇文章主要介紹了react中關(guān)于Context/Provider/Consumer傳參的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評論