• webpack5 (四)


    react-cli 中配置

    开发环境

    1. const path = require('path')
    2. const EslintWebpackPlugin = require('eslint-webpack-plugin')
    3. const HtmlWebpackPlugin = require('html-webpack-plugin')
    4. const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
    5. //封装处理样式配置
    6. const getStyleloaders = (pre)=>{
    7. return [
    8. 'style-loader',
    9. 'css-loader',
    10. // 处理 css 兼容性问题
    11. //需要配合 package.json 中的browserslist 来指定兼容性做到什么程度
    12. {
    13. loader: 'postcss-loader',
    14. options: {
    15. postcssOptions: {
    16. plugins: 'postcss-preset-env'
    17. }
    18. }
    19. },
    20. pre
    21. ].filter(Boolean)
    22. };
    23. //要用 commonjs的方式以对象的模式暴露出去
    24. module.exports = {
    25. // 入口文件
    26. entry: './src/main.js',
    27. // 出口文件
    28. output: {
    29. path: undefined,
    30. filename: 'static/js/[name].js',
    31. chunkFilename: 'static/js/[name].chunk.js',
    32. assetModuleFilename: 'static/media/[hash:10][etx][query]'
    33. },
    34. // 配置loader
    35. module: {
    36. rules: [
    37. // 处理 css
    38. {
    39. test: /\.css$/,
    40. use: getStyleloaders()
    41. },
    42. {
    43. test: /\.less$/,
    44. use: getStyleloaders('less-loader')
    45. },
    46. {
    47. test: /\.s[ac]ss$/,
    48. use: getStyleloaders('sass-loader')
    49. },
    50. {
    51. test: /\.styl$/,
    52. use: getStyleloaders('stylus-loader')
    53. },
    54. // 处理 图片
    55. {
    56. test:/\.(jpe?g|png|gif|webp|svg)$/,
    57. type:'asset',
    58. parser:{
    59. dataUrlCondition:{
    60. maxSize:10*1024,
    61. }
    62. }
    63. },
    64. //处理其他资源
    65. {
    66. test:/\.(woff2?|ttf)$/,
    67. type:'asset/resource'
    68. },
    69. // 处理 js
    70. {
    71. test:/\.jsx?$/,
    72. include:path.resolve(__dirname,'../src'),
    73. loader:'babel-loader',//babel 也需要有一个 babel 的配置文件
    74. options:{
    75. catchDirectory:true,
    76. catchCompression:false,
    77. plugins:[
    78. 'react-refresh/babel',//用来解决react脚手架下 js不能热更新的问题
    79. ]
    80. }
    81. }
    82. ]
    83. },
    84. // 配置plugin
    85. // 处理html
    86. plugin:[
    87. //eslint 插件也是需要有自己的配置文件
    88. new EslintWebpackPlugin({
    89. context:path.resolve(__dirname,'../src'),
    90. exclude:'node_modules',
    91. cache:true,
    92. cacheLocation:path.resolve(__dirname,'../node_modules/.catch/.eslintcache'),
    93. }),
    94. new HtmlWebpackPlugin({
    95. template:path.resolve(__dirname,'../public/index.html'),
    96. }),
    97. new ReactRefreshWebpackPlugin()//用来解决react脚手架下 js不能热更新的问题
    98. ],
    99. // 环境设置
    100. mode:'development',
    101. devtool:'cheap-module-source-map',
    102. optimization:{
    103. splitChunks:{
    104. chunks:'all'
    105. },
    106. runtimeChunk:{
    107. name:(entrypoint)=>`runtime~${entrypoint.name}.js`,
    108. }
    109. },
    110. //webpack 解析模块加载选项
    111. // 解决运行react项目时报错 Module not found:Error:can't resolve './App' in 'xx/xxx/xxx/x'
    112. resolve:{
    113. //自动补全文件扩展名
    114. extentions:['.jsx','.js','json']
    115. },
    116. devServer:{
    117. host:'localhost',
    118. port:3000,
    119. open:true,
    120. hot:true,
    121. historyApiFallback:true,//解决前端路由刷新404问题
    122. }
    123. }

    生产模式

    1. const path = require('path')
    2. const EslintWebpackPlugin = require('eslint-webpack-plugin')
    3. const HtmlWebpackPlugin = require('html-webpack-plugin')
    4. // 生产模式下不需要激活热更新
    5. // const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
    6. // CSS提取为单独文件
    7. const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    8. // css 压缩文件
    9. const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
    10. // js 压缩,使用css压缩后必须使用的插件
    11. const TerserWebpackPlugin = require('terser-webpack-plugin')
    12. // 图片 压缩插件
    13. const ImageMinimizerWebpackPlugin = require('image-minimizer-webpack-plugin')
    14. // 如果出现 网站图标 需要用该复制插件将其复制到dist目录下
    15. const CopyPlugin = require("copy-webpack-plugin");
    16. const getStyleloaders = (pre) => {
    17. return [
    18. // 'style-loader',
    19. MiniCssExtractPlugin.loader,//将style-loader替换为插件loader,打包为单独文件
    20. 'css-loader',
    21. {
    22. loader: 'postcss-loader',
    23. options: {
    24. postcssOptions: {
    25. plugins: 'postcss-preset-env'
    26. }
    27. }
    28. },
    29. pre
    30. ].filter(Boolean)
    31. };
    32. module.exports = {
    33. entry: './src/main.js',
    34. output: {
    35. path: path.resolve(__dirname, '../dist'),//设置出口文件路径
    36. filename: 'static/js/[name].[contenthash:10].js',//加入哈希值
    37. chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',//加入哈希值
    38. assetModuleFilename: 'static/media/[hash:10][etx][query]',
    39. clean: true,//将上次打包内容清空
    40. },
    41. module: {
    42. rules: [
    43. {
    44. test: /\.css$/,
    45. use: getStyleloaders()
    46. },
    47. {
    48. test: /\.less$/,
    49. use: getStyleloaders('less-loader')
    50. },
    51. {
    52. test: /\.s[ac]ss$/,
    53. use: getStyleloaders('sass-loader')
    54. },
    55. {
    56. test: /\.styl$/,
    57. use: getStyleloaders('stylus-loader')
    58. },
    59. {
    60. test: /\.(jpe?g|png|gif|webp|svg)$/,
    61. type: 'asset',
    62. parser: {
    63. dataUrlCondition: {
    64. maxSize: 10 * 1024,
    65. }
    66. }
    67. },
    68. {
    69. test: /\.(woff2?|ttf)$/,
    70. type: 'asset/resource'
    71. },
    72. {
    73. test: /\.jsx?$/,
    74. include: path.resolve(__dirname, '../src'),
    75. loader: 'babel-loader',
    76. options: {
    77. catchDirectory: true,
    78. catchCompression: false,
    79. // 生产模式下不需要激活热更新
    80. // plugins:[
    81. // 'react-refresh/babel',
    82. // ]
    83. }
    84. }
    85. ]
    86. },
    87. plugin: [
    88. new EslintWebpackPlugin({
    89. context: path.resolve(__dirname, '../src'),
    90. exclude: 'node_modules',
    91. cache: true,
    92. cacheLocation: path.resolve(__dirname, '../node_modules/.catch/.eslintcache'),
    93. }),
    94. new HtmlWebpackPlugin({
    95. template: path.resolve(__dirname, '../public/index.html'),
    96. }),
    97. // new ReactRefreshWebpackPlugin(),// 生产模式下不需要激活热更新
    98. // css 打包为单独文件插件
    99. new MiniCssExtractPlugin({
    100. filename: 'static/css/name.[contenthash:10].css',
    101. chunkFilename: 'static/css/name.[contenthash:10].chunk.css'
    102. }),
    103. // 复制插件 处理public下其他资源 如网站图标
    104. new CopyPlugin({
    105. patterns: [
    106. // 设置从何处复制到何处
    107. {
    108. from: path.resolve(__dirname,'../public'),
    109. to: path.resolve(__dirname,'../dist')
    110. },
    111. ],
    112. globOptions: {
    113. //设置忽略 index.html 文件
    114. ignore: ['**/index.html']
    115. }
    116. }),
    117. ],
    118. mode: 'production', // 改为生产模式
    119. devtool: 'source-map',//使用 source-map
    120. optimization: {
    121. splitChunks: {
    122. chunks: 'all'
    123. },
    124. runtimeChunk: {
    125. name: (entrypoint) => `runtime~${entrypoint.name}.js`,
    126. },
    127. // 压缩插件放在 optimization 对象内
    128. minimizer: [
    129. new CssMinimizerWebpackPlugin(),//压缩 css 插件,
    130. new TerserWebpackPlugin(),//压缩 js 插件,
    131. //压缩图片插件,
    132. new ImageMinimizerWebpackPlugin({
    133. minimizerOptions: {
    134. plugins: [
    135. ["gifsicle", { interlaced: true }],
    136. ["jpegtran", { progressive: true }],
    137. ["optipng", { optimizationLevel: 5 }],
    138. [
    139. "svgo",
    140. {
    141. plugins: extendDefaultPlugins([
    142. {
    143. name: "removeViewBox",
    144. active: false,
    145. },
    146. {
    147. name: "addAttributesToSVGElement",
    148. params: {
    149. attributes: [{ xmlns: "http://www.w3.org/2000/svg" }],
    150. },
    151. },
    152. ]),
    153. },
    154. ],
    155. ],
    156. },
    157. }),
    158. ]
    159. },
    160. resolve: {
    161. extentions: ['.jsx', '.js', 'json']
    162. },
    163. //生产模式不需要devsever
    164. // devServer:{
    165. // host:'localhost',
    166. // port:3000,
    167. // open:true,
    168. // hot:true,
    169. // historyApiFallback:true,
    170. // }
    171. }

    合并配置

    将生产模式和开发模式的配置进行合并,通过 process.env.NODE_ENV 的值来判断当前为生产环境还是开发环境。

    1. const isProd = process.env.NODE_ENV ==='production'
    2. //三元判断 加载哪一个插件
    3. isProd ? MiniCssExtractPlugin.loader : 'style-loader',
    4. //根据是否为生产模式来决定是否加载插件
    5. plugins:[
    6. !isProd && 'react-refresh/babel',//用来解决react脚手架下 js不能热更新的问题
    7. ].filter(Boolean)
  • 相关阅读:
    科研 | 中英文期刊分区介绍及查询方法
    读周志华《机器学习》第四章--决策树
    基于视觉重定位的室内AR导航APP的大创项目思路(2):改进的项目思路——建图和定位分离
    聚焦“碳中和”,成都超算中心牵手重庆大学唱好“成渝双城记”
    【无标题】
    ros远程订阅
    【创建型】生成器模式(Builder)
    上周热点回顾(11.21-11.27)
    剑指 Offer II 092. 翻转字符(DP,详细分析)
    VPS是什么?详解亚马逊云科技Amazon Lightsail(VPS)虚拟专用服务器
  • 原文地址:https://blog.csdn.net/Mqyyy/article/details/132664301