webpack5初试配置常用变更

简介:webpack5从0-1搭建项目 配置

### 步骤
mkdir webpack5-demo
cd webpack5-demo
npm/cnpm init -y
npm/cnpm install webpack webpack-cli -D

### 依照vue-cli脚手架新建好目录

### 安装相关依赖
npm/cnpm install webpack webpack-cli --save-dev
npm/cnpm install --save lodash
## 加载css
npm/cnpm install --save-dev style-loader css-loader
## 加载字体 加载 images 图像
自带的在 webpack 5 中,可以使用内置的 Asset Modules

### 多入口问题产生? --- 解决  
npm/cnpm install --save-dev html-webpack-plugin
如果我们更改了我们的一个入口起点的名称,甚至添加了一个新的入口,会发生什么?会在构建时重新命名生成的 bundle,但是我们的 index.html 文件仍然引用旧的名称。让我们用 HtmlWebpackPlugin 来解决这个问题

### 在每次构建前清理 /dist 文件夹,这样只会生成用到的文件
npm/cnpm install --save-dev clean-webpack-plugin

### 问题产生?调试困难
devtool: 'inline-source-map',
当 webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置。

### watch mode(观察模式)
package.json文件配置命令
"watch": "webpack --watch"
cnpm/npm run watch 

### 问题产生? 为了看到修改后的实际效果,你需要刷新浏览器
解决:
npm install --save-dev webpack-dev-server
webpack.config.js中配置
devServer: {
    contentBase: './dist',
}
package.json文件配置命令
"start": "webpack serve --open",
npm/cnpm start

### 使用 webpack-dev-middleware  参考官网:https://webpack.docschina.org/guides/development/
npm/cnpm install --save-dev express webpack-dev-middleware
webpack.config.js中配置
output: {
    publicPath: '/',
}
package.json文件配置命令
"server": "node server.js",
npm/cnpm run server

### vendor hash 发生变化是我们要修复的
optimization.moduleIds 设置为 'deterministic'

### 将文件标记为 side-effect-free(无副作用) 
通过 package.json 的 "sideEffects" 属性,来实现这种方式
"side effect(副作用)" 的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export。举例说明,例如 polyfill,它影响全局作用域,并且通常不提供 export。

"sideEffects": false
如果你的代码确实有一些副作用,可以改为提供一个数组;
如果在项目中使用类似 css-loader 并 import 一个 CSS 文件,则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:
"sideEffects": [
    "./src/xxx1.js",
    "./src/xxx2.js"
    ....,
    "*.css"
]

再或者
"sideEffects":["*.css","@babel/polyfill"],

sideEffects 和 usedExports(更多被认为是 tree shaking)是两种不同的优化方式。
sideEffects 更为有效 是因为它允许跳过整个模块/文件和整个文件子树

在使用 tree shaking 时必须有 ModuleConcatenationPlugin 的支持,您可以通过设置配置项 mode: "production" 以启用它。如果您没有如此做,请记得手动引入 ModuleConcatenationPlugin

总结:
webpack5的新特性:
1.更快的构建速度 【模块打包提供了一个可选的文件系统缓存。通过设置合适的缓存系统,我们可以大大加快构建速度,大大提高开发人员的工作效率】
2.更小的体积 【新版本的webpack对代码进行了模块化的管理,可以检测到无用代码,可以删除未使用的代码,可以删除模块内部的代码】
3.更智能的缓存优化 【对局部模块代码的修改,不会影响其它模块的缓存】
4.更灵活的模块组合 【允许多个Webpack构建协同工作。webpack5允许不同的应用程序从不同版本的webpack动态加载代码】
5.更高的版本要求 【nodejs的版本使用10.13以上版本,添加了实验性的WebAssembly,Async Web Assembly,Await等特性】

Webpack 5 增加了一个新的功能 "模块联邦",它允许多个 webpack 构建一起工作

嵌套的 tree-shaking 
CommonJs Tree Shaking 
内部模块 tree-shaking  【optimization.innerGraph】

单一文件目标的代码分割 
只允许启动单个文件的目标(如 node、WebWorker、electron main)现在支持运行时自动加载引导所需的依赖代码片段。
这允许对这些目标使用 chunks: "all" 和 optimization.runtimeChunk

MemoryCachePlugin 增加了内存缓存功能。FileCachePlugin 增加了持久性(文件系统)缓存。
FileCachePlugin 使用序列化机制将缓存项目持久化到磁盘上或从磁盘上恢复

插件目的在于解决 loader 无法实现的__其他事__

### 冲突问题  mini-css-extract-plugin 支持css分割 支持HMR
将css单独打包成一个文件的插件,它为每个包含css的js文件都创建一个css文件。它支持css和sourceMaps的按需加载
rules: [
    {
        test: /.(css|stylus)$/,
        use: [
            MiniCssExtractPlugin.loader,        
            'css-loader',                  
            {
            loader:'postcss-loader', // 跟MiniCssExtractPlugin.loader一起使用时 要添加 使用范围
            options:{
                plugins:[
                    require('autoprefixer')({
                        overrideBrowserslist: ['last 5 version', '>1%', 'ios 7']
                    })
                ]
            }
            },          
            'stylus-loader'                                 
        ],
        exclude:/node_modules/,
        include: [path.resolve(__dirname, 'src')]
    },
]

### 代码压缩
4.x版本后自动压缩
* development 不压缩代码    mode: 'development'  or   webpack --mode=development
* production     压缩代码,默认   mode: 'production'  or  webpack --mode=production
需要在webpack.config.js配置不启用压缩

// 安装 optimize-css-assets-webpack-plugin
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'); // 压缩css文件
new OptimizeCssAssetsWebpackPlugin()

之前使用 uglifyjs-webpack-plugin
const uglify = require('uglifyjs-webpack-plugin');
plugins:[
    new uglify()
]

关于sass sass-loader 8.0语法 9.0 配置
https://github.com/chuzhixin/vue-admin-beautiful/blob/master/vue.config.js

参考相关具体配置
https://github.com/ddzy/vue2-webpack5-template/blob/main/webpack.config.ts

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const { CleanWebpackPlugin } = require('clean-webpack-plugin');
 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 const devMode = process.env.NODE_ENV !== 'production'

 module.exports = {
    mode: 'development', // 开发环境 默认是生产
    devtool: 'inline-source-map',
    devServer: {
        contentBase: './dist',
    },
    //  entry: './src/main.js', // 单入口
    // 多入口
    entry:{
        index: {
            import: './src/main.js',
            dependOn: 'shared',
        },
        index2: {
            import: './src/main2.js',
            dependOn: 'shared',
        },
        shared: 'lodash',
    },
     // 出口
     output: {
        // [contenthash] substitution 将根据资源内容创建出唯一 hash。当资源内容发生变化时,[contenthash] 也会发生变化
        filename: 'js/[name].[contenthash].js',
        path: path.resolve(__dirname, 'dist'),
        pathinfo: false, // webpack 会在输出的 bundle 中生成路径信息 在打包数千个模块的项目中,这会导致造成垃圾回收性能压力
        publicPath: './' // 如果报错 Automatic publicPath is not supported in this browser
     },

    //  如果我们要在一个 HTML 页面上使用多个入口时,还需设置 optimization.runtimeChunk: 'single'
    optimization: {
        // 使用 optimization.splitChunks 配置选项之后
        // 需要注意的是,插件将 lodash 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了大小
        // splitChunks: {
        //     chunks: 'all',
        // },
        // runtimeChunk: 'single', // 打包额外生成了一个 runtime.bundle.js 文件
        // 将第三方库(library)(例如 lodash 或 react)提取到单独的 vendor chunk 文件中,是比较推荐的做法
        moduleIds: 'deterministic',
        usedExports: true, // 配置此项需要将 mode 配置设置成development,以确定 bundle 不会被压缩
        runtimeChunk: 'single',
        splitChunks: {
          cacheGroups: {
            vendor: {
              test: /[\/]node_modules[\/]/,
              name: 'vendors',
              chunks: 'all',
            },
          },
        },
    },
    // 应保证 loader 的先后顺序:'style-loader' 在前,而 'css-loader' 在后。如果不遵守此约定,webpack 可能会抛出错误
     module: {
        rules: [
          {
            test: /.css$/i,
            // MiniCssExtractPlugin.loader,// loader取代style.loader,作用,提取js中的css文件
            use: [MiniCssExtractPlugin.loader, 'css-loader'],
          },
          // 不用搞file-loader url-loader 用type定义
          {
            test: /.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset/resource',
            parser: {
                dataUrlCondition: {
                    maxSize: 8 * 1024,  //小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。
                },
            },
            generator: {
                filename: 'images/[base]',
            },
          },
          {
            test: /.(woff|woff2|eot|ttf|otf)$/i,
            type: 'asset/resource',
            generator: {
                filename: 'fonts/[base]',
            },
          },
        ]
      },
      plugins: [
        new MiniCssExtractPlugin({
            // filename: 'css/[name].[contenthash].css', //输出的文件名字
            filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
            chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
        }), // 抽离css
        // 如果不想在 watch 触发增量构建后删除 index.html 文件,可以在 CleanWebpackPlugin 中配置 cleanStaleWebpackAssets 选项 来实现
        new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
        new HtmlWebpackPlugin({
          title: 'Development', // 首页标题
        }),
      ],
      // 持久缓存 【性能优化】
      cache: {
        // 1. 将缓存类型设置为文件系统
        type: 'filesystem', // 可以在 "memory" 和 "filesystem" 间进行选择
        buildDependencies: {
          // 2. 将你的 config 添加为 buildDependency,以便在改变 config 时获得缓存无效
          config: [__filename],
          // 3. 如果你有其他的东西被构建依赖,你可以在这里添加它们
          // 注意,webpack、加载器和所有从你的配置中引用的模块都会被自动添加
        },
      },
 }

reset.css测试文件1

* {
    padding: 0;
    margin: 0;
}

@font-face {
    font-family: 'Nunito-Regular';
    src: url('./fonts/Nunito-Regular.ttf');
}

@font-face {
    font-family: 'Nunito-Bold';
    src: url('./fonts/Nunito-Bold.ttf');
}

@font-face {
    font-family: 'Nunito-SemiBold';
    src: url('./fonts/Nunito-SemiBold.ttf');
}

.hello {
    color: red;
    font-family: 'Nunito-Bold';
    background: url('./image/logo.png');
}

package.json测试文件

{
  "name": "webpack5-demo",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "webpack",
    "watch": "webpack --watch",
    "start": "webpack serve --open"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^5.0.1",
    "html-webpack-plugin": "^4.5.1",
    "mini-css-extract-plugin": "^1.3.5",
    "style-loader": "^2.0.0",
    "webpack": "^5.20.0",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  },
  "dependencies": {
    "lodash": "^4.17.20"
  }
}

 转载注明出处!!!谢谢合作!!!

原文地址:https://www.cnblogs.com/lhl66/p/14372748.html