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

基于webpack開(kāi)發(fā)react-cli的詳細(xì)步驟

 更新時(shí)間:2023年06月20日 10:45:23   作者:jieyucx  
這篇文章主要介紹了基于webpack開(kāi)發(fā)react-cli的詳細(xì)步驟,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

在前面的章節(jié)中我們學(xué)習(xí)了webpack的基礎(chǔ)配置(五大核心屬性),以及一些高級(jí)優(yōu)化配置(source map、Tree Shaking、 HMR、Code Split等),并且分別開(kāi)發(fā)了webpack.dev.js(開(kāi)發(fā)環(huán)境配置),和webpack.prod.js(生產(chǎn)環(huán)境配置)。

這一章節(jié)我們將兩個(gè)配置合并為一個(gè)整體配置,內(nèi)部差異通過(guò)process.env.NODE_ENV環(huán)境變量區(qū)分,并再結(jié)合一下react的插件,自己實(shí)現(xiàn)一個(gè)react-cli腳手架

一、react-cli開(kāi)發(fā)步驟

1. webpack.dev.js和webpack.prod.js的配置

webpack.dev.js

const path = require("path");
const EslintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
// 返回處理樣式loader函數(shù)
const getStyleLoaders = (pre) => {
  return [
    "style-loader",
    "css-loader",
    {
      // 處理css兼容性問(wèn)題
      // 配合package.json中browserslist來(lái)指定兼容性
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: ["postcss-preset-env"],
        },
      },
    },
    pre,
  ].filter(Boolean);
};
module.exports = {
  entry: "./src/main.js",
  output: {
    path: undefined,
    filename: "static/js/[name].js",
    chunkFilename: "static/js/[name].chunk.js",
    assetModuleFilename: "static/media/[hash:10][ext][query]",
  },
  module: {
    rules: [
      // 處理css
      {
        test: /\.css$/,
        use: getStyleLoaders(),
      },
      {
        test: /\.less$/,
        use: getStyleLoaders("less-loader"),
      },
      {
        test: /\.s[ac]ss$/,
        use: getStyleLoaders("sass-loader"),
      },
      {
        test: /\.styl$/,
        use: getStyleLoaders("stylus-loader"),
      },
      // 處理圖片
      {
        test: /\.(jpe?g|png|gif|webp|svg)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024,
          },
        },
      },
      // 處理其他資源
      {
        test: /\.(woff2?|ttf)$/,
        type: "asset/resource",
      },
      // 處理js
      {
        test: /\.jsx?$/,
        include: path.resolve(__dirname, "../src"),
        loader: "babel-loader",
        options: {
          cacheDirectory: true,
          cacheCompression: false,
          plugins: [
            "react-refresh/babel", // 激活js的HMR
          ],
        },
      },
    ],
  },
  // 處理html
  plugins: [
    new EslintWebpackPlugin({
      context: path.resolve(__dirname, "../src"),
      exclude: "node_modules",
      cache: true,
      cacheLocation: path.resolve(__dirname, "../node_modules/.cache/.eslintcache"),
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "../public/index.html"),
    }),
    new ReactRefreshWebpackPlugin(), // 激活js的HMR
  ],
  mode: "development",
  devtool: "cheap-module-source-map",
  optimization: {
    splitChunks: {
      chunks: "all",
    },
    runtimeChunk: {
      name: (entrypoint) => `runtime~${entrypoint.name}.js`,
    },
  },
  // webpack解析模塊加載選項(xiàng)
  resolve: {
    // 自動(dòng)補(bǔ)全文件擴(kuò)展名
    extensions: [".jsx", ".js", ".json"],
  },
  devServer: {
    host: "localhost",
    port: 3000,
    open: true,
    hot: true, // 開(kāi)啟HMR
    historyApiFallback: true, // 解決前端路由刷新404問(wèn)題
  },
};

webpack.prod.js

const path = require("path");
const EslintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
const TerserWebpackPlugin = require("terser-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
// 返回處理樣式loader函數(shù)
const getStyleLoaders = (pre) => {
  return [
    MiniCssExtractPlugin.loader,
    "css-loader",
    {
      // 處理css兼容性問(wèn)題
      // 配合package.json中browserslist來(lái)指定兼容性
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: ["postcss-preset-env"],
        },
      },
    },
    pre,
  ].filter(Boolean);
};
module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "../dist"),
    filename: "static/js/[name].[contenthash:10].js",
    chunkFilename: "static/js/[name].[contenthash:10].chunk.js",
    assetModuleFilename: "static/media/[hash:10][ext][query]",
    clean: true,
  },
  module: {
    rules: [
      // 處理css
      {
        test: /\.css$/,
        use: getStyleLoaders(),
      },
      {
        test: /\.less$/,
        use: getStyleLoaders("less-loader"),
      },
      {
        test: /\.s[ac]ss$/,
        use: getStyleLoaders("sass-loader"),
      },
      {
        test: /\.styl$/,
        use: getStyleLoaders("stylus-loader"),
      },
      // 處理圖片
      {
        test: /\.(jpe?g|png|gif|webp|svg)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024,
          },
        },
      },
      // 處理其他資源
      {
        test: /\.(woff2?|ttf)$/,
        type: "asset/resource",
      },
      // 處理js
      {
        test: /\.jsx?$/,
        include: path.resolve(__dirname, "../src"),
        loader: "babel-loader",
        options: {
          cacheDirectory: true,
          cacheCompression: false,
        },
      },
    ],
  },
  // 處理html
  plugins: [
    new EslintWebpackPlugin({
      context: path.resolve(__dirname, "../src"),
      exclude: "node_modules",
      cache: true,
      cacheLocation: path.resolve(__dirname, "../node_modules/.cache/.eslintcache"),
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "../public/index.html"),
    }),
    new MiniCssExtractPlugin({
      filename: "static/css/[name].[contenthash:10].css",
      chunkFilename: "static/css/[name].[contenthash:10].chunk.css",
    }),
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, "../public"),
          to: path.resolve(__dirname, "../dist"),
          globOptions: {
            // 忽略index.html文件
            ignore: ["**/index.html"],
          },
        },
      ],
    }),
  ],
  mode: "production",
  devtool: "source-map",
  optimization: {
    splitChunks: {
      chunks: "all",
    },
    runtimeChunk: {
      name: (entrypoint) => `runtime~${entrypoint.name}.js`,
    },
    minimizer: [
      new CssMinimizerWebpackPlugin(),
      new TerserWebpackPlugin(),
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminGenerate,
          options: {
            plugins: [
              ["gifsicle", { interlaced: true }],
              ["jpegtran", { progressive: true }],
              ["optipng", { optimizationLevel: 5 }],
              [
                "svgo",
                {
                  plugins: [
                    "preset-default",
                    "prefixIds",
                    {
                      name: "sortAttrs",
                      params: {
                        xmlnsOrder: "alphabetical",
                      },
                    },
                  ],
                },
              ],
            ],
          },
        },
      }),
    ],
  },
  // webpack解析模塊加載選項(xiàng)
  resolve: {
    // 自動(dòng)補(bǔ)全文件擴(kuò)展名
    extensions: [".jsx", ".js", ".json"],
  },
};

2. 下載cross-env 獲取環(huán)境變量,配置打包命令

npm i cross-env -D

更改package.json中的打包方式

package.json

"scripts": {
    "start": "npm run dev",
    "dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config ./config/webpack.config.js"
  },

3. 合并生產(chǎn)和開(kāi)發(fā)配置為webpack.config.js

完整代碼如下:

const path = require("path");
const EslintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
const TerserWebpackPlugin = require("terser-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
// 獲取cross-env定義的環(huán)境變量
const isProduction = process.env.NODE_ENV === "production";
// 返回處理樣式loader函數(shù)
const getStyleLoaders = (pre) => {
  return [
    isProduction ? MiniCssExtractPlugin.loader : "style-loader",
    "css-loader",
    {
      // 處理css兼容性問(wèn)題
      // 配合package.json中browserslist來(lái)指定兼容性
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: ["postcss-preset-env"],
        },
      },
    },
    pre && {
      loader: pre,
      options:
        pre === "less-loader"
          ? {
              // antd自定義主題配置
              // 主題色文檔:https://ant.design/docs/react/customize-theme-cn#Ant-Design-%E7%9A%84%E6%A0%B7%E5%BC%8F%E5%8F%98%E9%87%8F
              lessOptions: {
                modifyVars: { "@primary-color": "#1DA57A" },
                javascriptEnabled: true,
              },
            }
          : {},
    },
  ].filter(Boolean);
};
module.exports = {
  entry: "./src/main.js",
  output: {
    path: isProduction ? path.resolve(__dirname, "../dist") : undefined, // 開(kāi)發(fā)環(huán)境不指定輸出目錄,使用默認(rèn)的輸出目錄
    filename: isProduction ? "static/js/[name].[contenthash:10].js" : "static/js/[name].js", // 生產(chǎn)環(huán)境使用contenthash,開(kāi)發(fā)環(huán)境使用hash
    chunkFilename: isProduction ? "static/js/[name].[contenthash:10].chunk.js" : "static/js/[name].chunk.js", 
    assetModuleFilename: "static/media/[hash:10][ext][query]", // 配置圖片資源輸出的文件名
    clean: true, // 每次打包前清除dist目錄
  },
  module: {
    rules: [
      // 處理css
      {
        test: /\.css$/,
        use: getStyleLoaders(),
      },
      {
        test: /\.less$/,
        use: getStyleLoaders("less-loader"),
      },
      {
        test: /\.s[ac]ss$/,
        use: getStyleLoaders("sass-loader"),
      },
      {
        test: /\.styl$/,
        use: getStyleLoaders("stylus-loader"),
      },
      // 處理圖片
      {
        test: /\.(jpe?g|png|gif|webp|svg)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024,
          },
        },
      },
      // 處理其他資源
      {
        test: /\.(woff2?|ttf)$/,
        type: "asset/resource",
      },
      // 處理js
      {
        test: /\.jsx?$/,
        include: path.resolve(__dirname, "../src"),
        loader: "babel-loader",
        options: {
          cacheDirectory: true,
          cacheCompression: false,
          plugins: [
            !isProduction && "react-refresh/babel", // 激活js的HMR
          ].filter(Boolean),
        },
      },
    ],
  },
  // 處理html
  plugins: [
    new EslintWebpackPlugin({ // eslint檢查
      context: path.resolve(__dirname, "../src"), // 指定檢查的目錄
      exclude: "node_modules", // 指定排除的目錄
      cache: true, // 開(kāi)啟緩存,提升eslint檢查速度
      cacheLocation: path.resolve(__dirname, "../node_modules/.cache/.eslintcache"), // 指定緩存文件存放位置
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "../public/index.html"), // 指定html模板
    }),
    isProduction &&
      new MiniCssExtractPlugin({ // 提取css為單獨(dú)文件
        filename: "static/css/[name].[contenthash:10].css", // 提取的css文件名
        chunkFilename: "static/css/[name].[contenthash:10].chunk.css", // 提取的css chunk文件名
      }),
    isProduction &&
      new CopyPlugin({ // 將public目錄下的文件拷貝到dist目錄下
        patterns: [
          {
            from: path.resolve(__dirname, "../public"),
            to: path.resolve(__dirname, "../dist"),
            globOptions: {
              // 忽略index.html文件
              ignore: ["**/index.html"],
            },
          },
        ],
      }),
    !isProduction && new ReactRefreshWebpackPlugin(), // 開(kāi)發(fā)環(huán)境開(kāi)啟HMR
  ].filter(Boolean),
  mode: isProduction ? "production" : "development",
  devtool: isProduction ? "source-map" : "cheap-module-source-map", // 配置source-map映射, 生產(chǎn)環(huán)境使用source-map,開(kāi)發(fā)環(huán)境使用cheap-module-source-map
  optimization: {
    splitChunks: {
      chunks: "all",
      cacheGroups: {
        // react react-dom react-router-dom 一起打包成一個(gè)js文件
        react: {
          test: /[\\/]node_modules[\\/]react(.*)?[\\/]/,
          name: "chunk-react",
          priority: 40,
        },
        // antd 單獨(dú)打包
        antd: {
          test: /[\\/]node_modules[\\/]antd[\\/]/,
          name: "chunk-antd",
          priority: 30,
        },
        // 剩下node_modules單獨(dú)打包
        libs: {
          test: /[\\/]node_modules[\\/]/,
          name: "chunk-libs",
          priority: 20,
        },
      },
    },
    runtimeChunk: {
      name: (entrypoint) => `runtime~${entrypoint.name}.js`, // 為每個(gè)入口添加一個(gè)runtime文件
    },
    // 是否需要進(jìn)行壓縮
    minimize: isProduction, // 生產(chǎn)環(huán)境壓縮
    minimizer: [
      new CssMinimizerWebpackPlugin(), // 壓縮css
      new TerserWebpackPlugin(), // 壓縮js
      new ImageMinimizerPlugin({ // 壓縮圖片
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminGenerate,
          options: {
            plugins: [
              ["gifsicle", { interlaced: true }],
              ["jpegtran", { progressive: true }],
              ["optipng", { optimizationLevel: 5 }],
              [
                "svgo",
                {
                  plugins: [
                    "preset-default",
                    "prefixIds",
                    {
                      name: "sortAttrs",
                      params: {
                        xmlnsOrder: "alphabetical",
                      },
                    },
                  ],
                },
              ],
            ],
          },
        },
      }),
    ],
  },
  // webpack解析模塊加載選項(xiàng)
  resolve: {
    // 自動(dòng)補(bǔ)全文件擴(kuò)展名
    extensions: [".jsx", ".js", ".json"],
  },
  devServer: {
    host: "localhost",
    port: 3000,
    open: true,
    hot: true, // 開(kāi)啟HMR
    historyApiFallback: true, // 解決前端路由刷新404問(wèn)題
  },
  performance: false, // 關(guān)閉性能分析,提升打包速度
};

二、react-cli新增配置介紹

1. 定義生產(chǎn)環(huán)境變量

// 獲取cross-env定義的環(huán)境變量
const isProduction = process.env.NODE_ENV === "production";

2. 借助CopyPlugin ,將public目錄下的文件拷貝到dist目錄下

    const CopyPlugin = require("copy-webpack-plugin");
    plugins: [
     new CopyPlugin({ // 將public目錄下的文件拷貝到dist目錄下
        patterns: [
          {
            from: path.resolve(__dirname, "../public"),
            to: path.resolve(__dirname, "../dist"),
            globOptions: {
              // 忽略index.html文件
              ignore: ["**/index.html"],
            },
          },
        ],
      }),
    ]

3. 借助ReactRefreshWebpackPlugin 開(kāi)啟開(kāi)發(fā)環(huán)境HMR

const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
module:{
	rules:[
		// 處理js
      {
        test: /\.jsx?$/,
        include: path.resolve(__dirname, "../src"),
        loader: "babel-loader",
        options: {
          cacheDirectory: true,
          cacheCompression: false,
          plugins: [
            !isProduction && "react-refresh/babel", // 激活js的HMR
          ].filter(Boolean),
        },
      },
	]
},
plugins: [
	!isProduction && new ReactRefreshWebpackPlugin(), // 開(kāi)發(fā)環(huán)境開(kāi)啟HMR
]

4. 解析模塊,自動(dòng)補(bǔ)全擴(kuò)展名

  // webpack解析模塊加載選項(xiàng)
  resolve: {
    // 自動(dòng)補(bǔ)全文件擴(kuò)展名
    extensions: [".jsx", ".js", ".json"],
  },

5. 配置 historyApiFallback: true, 解決前端路由刷新404問(wèn)題

  devServer: {
    host: "localhost",
    port: 3000,
    open: true,
    hot: true, // 開(kāi)啟HMR
    historyApiFallback: true, // 解決前端路由刷新404問(wèn)題
  },

6. 關(guān)閉性能分析,提升打包速度

performance: false, // 關(guān)閉性能分析,提升打包速度

7. 通過(guò)cssloader自定義antd主題

pre && {
      loader: pre,
      options:
        pre === "less-loader"
          ? {
              // antd自定義主題配置
              lessOptions: {
                modifyVars: { "@primary-color": "#1DA57A" },
                javascriptEnabled: true,
              },
            }
          : {},
    },

8. 關(guān)閉多進(jìn)程打包

在項(xiàng)目沒(méi)有達(dá)到一定規(guī)模之前,開(kāi)啟多進(jìn)程反而會(huì)減慢打包速度

9. 模塊分離打包

cacheGroups: {
        // react react-dom react-router-dom 一起打包成一個(gè)js文件
        react: {
          test: /[\\/]node_modules[\\/]react(.*)?[\\/]/,
          name: "chunk-react",
          priority: 40,
        },
        // antd 單獨(dú)打包
        antd: {
          test: /[\\/]node_modules[\\/]antd[\\/]/,
          name: "chunk-antd",
          priority: 30,
        },
        // 剩下node_modules單獨(dú)打包
        libs: {
          test: /[\\/]node_modules[\\/]/,
          name: "chunk-libs",
          priority: 20,
        },
      }, 

到此這篇關(guān)于基于webpack開(kāi)發(fā)react-cli的文章就介紹到這了,更多相關(guān)webpack開(kāi)發(fā)react-cli內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解基于webpack搭建react運(yùn)行環(huán)境

    詳解基于webpack搭建react運(yùn)行環(huán)境

    本篇文章主要介紹了詳解基于webpack搭建react運(yùn)行環(huán)境,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 優(yōu)雅的在React項(xiàng)目中使用Redux的方法

    優(yōu)雅的在React項(xiàng)目中使用Redux的方法

    這篇文章主要介紹了優(yōu)雅的在React項(xiàng)目中使用Redux的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • ReactQuery系列之?dāng)?shù)據(jù)轉(zhuǎn)換示例詳解

    ReactQuery系列之?dāng)?shù)據(jù)轉(zhuǎn)換示例詳解

    這篇文章主要為大家介紹了ReactQuery系列之?dāng)?shù)據(jù)轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • React JSX基礎(chǔ)語(yǔ)法教程示例

    React JSX基礎(chǔ)語(yǔ)法教程示例

    這篇文章主要為大家介紹了React JSX基礎(chǔ)語(yǔ)法教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • React?Context原理深入理解源碼示例分析

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

    這篇文章主要為大家介紹了React?Context原理深入理解源碼示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React jsx文件介紹與使用方式

    React jsx文件介紹與使用方式

    這篇文章主要介紹了React jsx文件介紹與使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 使用react完成點(diǎn)擊返回頂部操作

    使用react完成點(diǎn)擊返回頂部操作

    本文主要介紹了使用react完成點(diǎn)擊返回頂部操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 編寫(xiě)簡(jiǎn)潔React組件的小技巧

    編寫(xiě)簡(jiǎn)潔React組件的小技巧

    這篇文章主要介紹了編寫(xiě)簡(jiǎn)潔React組件的小技巧,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • React中10種Hook的使用介紹

    React中10種Hook的使用介紹

    Hook 是 React 16.8 的新增特性,本文主要介紹了10種Hook的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • React Native 混合開(kāi)發(fā)多入口加載方式詳解

    React Native 混合開(kāi)發(fā)多入口加載方式詳解

    這篇文章主要介紹了React Native 混合開(kāi)發(fā)多入口加載方式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評(píng)論