2.png 0
8i98

家事,国事,天下事,事事关心

2022-03-13

webpack5 教程

2022-06-10 0 35 web前端社区

2.png 0 8i98

  1. webpack介绍

    webpack 是一个用于JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles(包),它们均为静态资源,用于展示你的内容。
    mvvm图片
    Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求。

  2. webpack安装

    1. 在安装 Webpack 前,你本地环境需要支持 node.js。
    2. 如果 npm 安装速度慢,可以用 cnpm。
    3. cnpm install webpack -g 全局安装webpack。
    4. cnpm install webpack-cli -g 全局安装webpack-cli。

    cnpm i webpack webpack-cli -g 同时全局安装两个模块。
    一般全局安装了webpack还需要项目本地项目安装cnpm i webpack webpack-cli 这是由于webpack requet的相关模块引用的是项目目录里的,这是node.js的机制问题。
    webpack4.0 以后,似乎执行方式就发生了改变,不再是 webpack 一波流,而是多了一个 webpack-cli。webpack4中webpack-cli是合在webpack中。所以在命令行运行 webpack 命令的同时,会提示让你再装一个 webpack-cli。
    webpack-cli 是一个webpack简易客户端,用来以webpack协议连接相应服务

  3. webpack打包流程

    1. 创建app目录(文件夹)。
    2. npm init 初始化项目。
    3. npm install webpack webpack-cli --save-dev 把webpack和webpack-cli安装到当前目录,并添加package.json的dev环境。
    4. 创建 src目录,在 src 目录下添加 index1.js 文件,代码如下:

    document.write("It work in index1");

    1. 在 app 目录下添加 index.html 文件,代码如下:
    1. <html>
    2. <head>
    3. <meta charset="utf-8">
    4. </head>
    5. <body>
    6. <script type="text/javascript" src="dist/main.js" charset="utf-8"></script>
    7. </body>
    8. </html>
    1. webpack 命令来打包:
      webpack index1.js
      执行以上命令会编译 index1.js ,编译后的文件名为main.js,并且放到dist文件夹(如果项目中没有该文件夹会自动创建):
    1. asset main.js 39 bytes [emitted] [minimized] (name: main)
    2. ./src/index1.js 38 bytes [built] [code generated]
    3. WARNING in configuration
    4. The 'mode' option has not been set, webpack will fallback to 'production' for this value.
    5. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
    6. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
    7. webpack 5.64.4 compiled with 1 warning in 207 ms
    • 由于没有指定打包的环境,所以会有警告信息,一般我们指定环境会单独配置到webpack.config.js文件。
    • 项目结构
      mvvm图片
  4. webpack打包多文件

    1. 创建另外一个 js 文件 index2.js,代码如下所示:
    1. const go = ()=>{
    2. document.write("my work in index2.js");
    3. }
    4. export default go;
    1. 更新 index1.js 文件,代码如下:
    1. import go from "./index2";
    2. go();
    3. document.write("it work in index1.js")
    1. webpack 命令来打包:
      webpack index1.js
      webpack 根据模块的依赖关系进行静态分析,这些文件(模块)会被包含到 main.js 文件中。Webpack 会给每个模块分配一个唯一的 id 并通过这个 id 索引和访问模块。 在页面启动时,会先执行 index1.js 中的代码,其它模块会在运行 require 的时候再执行。
  5. LOADER CSS打包

    Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。

    所以如果我们需要在应用中添加 css 文件,就需要使用到 css-loader 和 style-loader,他们做两件不同的事情,css-loader 会遍历 CSS 文件,然后找到 url() 表达式然后处理他们,style-loader 会把原来的 CSS 代码插入页面中的一个 style 标签中。

    接下来我们使用以下命令来安装 css-loader 和 style-loader(全局安装需要参数 -g)。

    cnpm install css-loader style-loader --save-dev

    执行以上命令后,会再当前目录生成 node_modules 目录,它就是 css-loader 和 style-loader 的安装目录。

    1. 创建一个 style.css 文件,代码如下:
    1. body {
    2. background: yellow;
    3. }
    1. 修改 index1.js 文件,代码如下:
    1. require("!style-loader!css-loader!./style.css");
    2. document.write(require("./index2.js"));
    1. 使用执行打包命令打包
      webpack index1.js bundle.js
    2. require CSS 文件的时候都要写 loader 前缀 !style-loader!css-loader!,当然我们可以根据模块类型(扩展名)来自动绑定需要的 loader。一般会把loader写到专用的配置文件中。
  6. 配置文件web.config.js

    我们可以将一些编译选项放在配置文件中,以便于统一管理:

    1. 创建 webpack.config.js 配置文件,代码如下所示:

      1. module.exports = {
      2. entry: './src/index1.js', // 打包入口
      3. output: {
      4. path: __dirname + '/dist', // 输出路径
      5. filename: 'main.js' // 输出文件名
      6. },
      7. mode: "development",// 打包环境设置 production 和 development
      8. module: {
      9. rules: [ // 其中包含各种loader的使用规则
      10. {
      11. test: /\.css$/, // 正则表达式,表示打包.css后缀的文件
      12. use: ['style-loader','css-loader'] // 针对css文件使用的loader,注意有先后顺序,数组项越靠后越先执行
      13. }
      14. ]
      15. },
      16. watch: true // 监听文件改动并自动打包
      17. };

      接下来我们只需要执行 webpack 命令即可生成 main.js 文件

    2. module使用方法:
      rules:一个数组,存放各种Loader
      test:正则表达式,用来匹配不同的文件名后缀
      loader:有多种使用方法:

      1. {
      2. test:/\.js$/,
      3. loader:'babel-loader' //只有一个loader时
      4. }
      5. {
      6. test:/\.css$/,
      7. use:['style-loader','css-loader'] //多个loader,从右往左加载
      8. }
      9. {
      10. test:/\.css$/,
      11. use:[
      12. 'style-loader', //多个loader混合使用
      13. { //loader要设置相关参数时可以使用对象
      14. loader:'css-loader',
      15. options:{
      16. minimize:true
      17. }
      18. }
      19. ]
      20. }
    3. 可以通过mode选项为webpack指定一些默认的配置。mode分为development/production,默认为production。每个选项的默认配置如下(common指两个配置项都存在的属性):

    • common
    1. //parent chunk中解决了的chunk会被删除
    2. optimization.removeAvailableModules:true
    3. //删除空的chunks
    4. optimization.removeEmptyChunks:true
    5. //合并重复的chunk
    6. optimization.mergeDuplicateChunks:true
    • development
    1. //调试
    2. devtool:eval
    3. //缓存模块, 避免在未更改时重建它们。
    4. cache:true
    5. //缓存已解决的依赖项, 避免重新解析它们。
    6. module.unsafeCache:true
    7. //在 bundle 中引入「所包含模块信息」的相关注释
    8. output.pathinfo:true
    9. //在可能的情况下确定每个模块的导出,被用于其他优化或代码生成。
    10. optimization.providedExports:true
    11. //找到chunk中共享的模块,取出来生成单独的chunk
    12. optimization.splitChunks:true
    13. //为 webpack 运行时代码创建单独的chunk
    14. optimization.runtimeChunk:true
    15. //编译错误时不写入到输出
    16. optimization.noEmitOnErrors:true
    17. //给模块有意义的名称代替ids
    18. optimization.namedModules:true
    19. //给模chunk有意义的名称代替ids
    20. optimization.namedChunks:true
    • production
    1. //性能相关配置
    2. performance:{hints:"error"....}
    3. //某些chunk的子chunk已一种方式被确定和标记,这些子chunks在加载更大的块时不必加载
    4. optimization.flagIncludedChunks:true
    5. //给经常使用的ids更短的值
    6. optimization.occurrenceOrder:true
    7. //确定每个模块下被使用的导出
    8. optimization.usedExports:true
    9. //识别package.json or rules sideEffects 标志
    10. optimization.sideEffects:true
    11. //尝试查找模块图中可以安全连接到单个模块中的段。- -
    12. optimization.concatenateModules:true
    13. //使用uglify-js压缩代码
    14. optimization.minimize:true
    1. 修改package.json 包的scripts字段,把webpack命令改为用npm build打包。
    1. "scripts": {
    2. "test": "fds",
    3. "build": "webpack"
    4. }

    npm build 命令相当于执行的webpack 命令,可以打包文件。

  7. css打包进阶

    插件在 webpack 的配置信息 plugins 选项中指定,用于完成一些 loader 不能完成的工。
    webpack 自带一些插件,你可以通过 cnpm 安装一些插件。

    • 使用插件MiniCssExtractPlugin 将css打包到一个文件中。
      使用css-loader+style-loader的方式是将样式打包进js文件,然后以style标签的形式嵌入页面。css样式与js文件混在一起可能导致一些样式混乱,所以使用插件将css样式统一打包进一个css文件,然后以link标签的形式嵌入页面进行资源请求。
      webpack3通常使用的是ExtractWebpackPlugin,但在webpack4中已不再支持,官方推荐使用MiniCssExtractPlugin进行替代。
      首先安装 :
      cnpm i -D mini-css-extract-plugin
      修改配置文件
    1. const miniCssExtractPlugin=require('mini-css-extract-plugin');
    2. module.exports = {
    3. entry: './src/index1.js', // 打包入口
    4. output: {
    5. path: __dirname + '/dist', // 输出路径
    6. filename: 'main.js' // 输出文件名
    7. },
    8. mode: "development",// 打包环境设置 production 和 development
    9. module: {
    10. rules: [ // 其中包含各种loader的使用规则
    11. {
    12. test: /\.css$/,
    13. use: [
    14. {
    15. loader:miniCssExtractPlugin.loader
    16. },
    17. 'css-loader'
    18. ]
    19. }
    20. ]
    21. },
    22. plugins: [
    23. new miniCssExtractPlugin({
    24. filename:'[name].css' //输出的css文件名,放置在dist目录下
    25. })
    26. ],
    27. watch: true // 监听文件改动并自动打包
    28. };
    • 压缩css/js代码
      使用optimize-css-assets-webpack-plugin插件来压缩css代码。
      安装 npm i -D optimize-css-assets-webpack-plugin
      修改配置文件
    1. const miniCssExtractPlugin=require('mini-css-extract-plugin'); // 引入css单独打包插件
    2. const opimizeCss=require('optimize-css-assets-webpack-plugin'); // 引入压缩css插件
    3. module.exports = {
    4. entry: './src/index1.js', // 打包入口
    5. output: {
    6. path: __dirname + '/dist', // 输出路径
    7. filename: 'main.js' // 输出文件名
    8. },
    9. optimization:{
    10. minimizer:[
    11. new opimizeCss()
    12. ]
    13. },
    14. mode: "production",// 打包环境设置 production 和 development
    15. module: {
    16. rules: [ // 其中包含各种loader的使用规则
    17. {
    18. test: /\.css$/,
    19. use: [
    20. {
    21. loader:miniCssExtractPlugin.loader
    22. },
    23. 'css-loader', // 解析css
    24. ]
    25. }
    26. ]
    27. },
    28. plugins: [
    29. new miniCssExtractPlugin({
    30. filename:'[name].css' //输出的css文件名,放置在dist目录下
    31. })
    32. ],
    33. watch: true // 监听文件改动并自动打包
    34. };

    打包查看生成的main.css文件,css会被压缩(去掉多余的空格和换行)。
    webpack5的producttion环境打包js会自动压缩。如果其他版本的webpack没有压缩js
    可以使用npm i -D uglifyjs-webpack-plugin 插件压缩js。
    配置如下:

    1. //webpack.config.js
    2. const uglifyJsWebpackPlugin=require('uglifyjs-webpack-plugin')
    3. module.exports = {
    4. optimization:{
    5. minimizer:[
    6. new uglifyJsWebpackPlugin({
    7. cache:true, //是否缓存
    8. parallel:true, //是否并发打包,同时打包多个文件
    9. sourceMap:true //打包后的代码与源码的映射,方便调试
    10. })
    11. ...
    12. ]
    13. ...
    14. }
  8. 打包scss文件

    npm install sass-loader node-sass --save-dev 安装sass文件的loader。
    配置web.config.js加入打包.scss文件:

    1. {
    2. test: /\.scss$/,
    3. use: [
    4. {
    5. loader:miniCssExtractPlugin.loader,
    6. },
    7. 'css-loader', // 解析css
    8. 'sass-loader'
    9. ]
    10. }
  9. js中图片打包

    webpack5之前图片打包关键要用到file-loader或url-loader,其中url-loader与file-loader功能基本一致,只不过url-loader能将小于某个大小的图片进行base64格式的转化处理,我们这里使用url-loader。
    安装file-loader并配置 npm i -D file-loader 并配置web.config.js文件。

    webpack5之后可以直接使用asset处理图片,不必再配置file-loader或url-loader。能更好的简化使用。且它是webpack5内置模块,不必额外进行安装其它东西,配置web.config.js:

    1. const miniCssExtractPlugin=require('mini-css-extract-plugin');
    2. const opimizeCss=require('optimize-css-assets-webpack-plugin');
    3. module.exports = {
    4. entry: './src/index1.js', // 打包入口
    5. output: {
    6. path: __dirname + '/dist', // 输出路径
    7. filename: 'main.js', // 输出文件名
    8. assetModuleFilename: "imgs/[name].[hash:8].[ext]"
    9. },
    10. optimization:{
    11. minimizer:[
    12. new opimizeCss()
    13. ]
    14. },
    15. mode: "production",// 打包环境设置 production 和 development
    16. module: {
    17. rules: [ // 其中包含各种loader的使用规则
    18. {
    19. test: /\.css$/,
    20. use: [
    21. {
    22. loader:miniCssExtractPlugin.loader,
    23. },
    24. 'css-loader', // 解析css
    25. ]
    26. },
    27. {
    28. test: /\.(png|jpg|gif|svg|jpeg)$/,
    29. type: "asset/resource",
    30. generator: {
    31. filename: 'imgs/[name].[hash:8].[ext]', //打包后的图片名称name是图片名,[hash:8]是随机8位的hash值 [ext]指图片格式
    32. }
    33. }
    34. ]
    35. },
    36. plugins: [
    37. new miniCssExtractPlugin({
    38. filename:'[name].css' //输出的css文件名,放置在dist目录下
    39. })
    40. ],
    41. watch: true // 监听文件改动并自动打包
    42. };

    资源模块类型通过添加四种新的模块类型,来代替Loader。type的类型有:

    1. asset/resource 发送一个单独的文件并导出URL,替代file-loader
    2. asset/inline 导出一个资源的data URL,替代url-loader
    3. asset/source 到处资源的源代码,之前通过使用raw-loader实现。
    4. asset在导出一个data URL和发送一个单独的文件之间做选择,之前通过url-loader+limit属性实现。

    在目录下新增一个imgs文件夹,再在imgs中添加一张图片“2.png”。

    1. 修改index1.js
    1. var img = new Image();
    2. img.src = '../imgs/2.png';
    3. document.body.appendChild(img);
    1. 如果不使用Webpack打包,正常情况下只要路径正确图片是能够正常显示的。然而,当使用Webpack打包后,我们会发现 图片并未被成功打包到dist目录,自然图片也无法显示出来。
    2. 这其实是因为Webpack并不知道’../imgs/2.png’是一张图片,如果要正常打包的话需要先将图片资源加载进来,然后再将其作为图片路径添加至图片对象。具体代码如下:
    1. var imgSrc = require('../imgs/2.png');// js中图片需要用require引入。
    2. var img = new Image();
    3. img.src = imgSrc;
    4. document.body.appendChild(img);
    1. css中图片打包按常规写法。
  10. HTML文件打包

    使用插件(plugins)对HTML文件进行处理(html-webpack-plugin)

    1. 下载安装 cnpm i -D html-webpack-plugin
    2. 配置插件到web.config.js
    1. const HtmlWebpackPlugin=require('html-webpack-plugin');
    2. new HtmlWebpackPlugin({
    3. // 以根目录中的index.html文件作为模板来自动生成dist/index.html文件
    4. // 注意,这里是相对根目录而言的,因为脚本的上下文是在根目录下
    5. template: "./index.html", // 打包的html文件
    6. inject: 'head', // 脚本注入的位置,可以是head, body,或者为 false默认
    7. filename: "index.html", // 打包后的文件名
    8. chunks: ['main'], //引入指定js文件
    9. minify: {
    10. collapseWhitespace: true,
    11. removeComments: true
    12. }
    13. })
    1. 打包多个html文件的配置:
    1. new HtmlWebpackPlugin({
    2. template: "./index.html",
    3. filename: "index.html",
    4. chunks: ['main'],
    5. minify: {
    6. collapseWhitespace: true,
    7. removeComments: true
    8. }
    9. }),
    10. new HtmlWebpackPlugin({
    11. template: "./index2.html",
    12. filename: "index2.html",
    13. chunks: ['index2js'],
    14. minify: {
    15. collapseWhitespace: true,
    16. removeComments: true
    17. }
    18. })
  11. 打包多html引入不同js文件配置。

    webpack.config.js配置如下:

    1. const miniCssExtractPlugin=require('mini-css-extract-plugin');
    2. const opimizeCss=require('optimize-css-assets-webpack-plugin');
    3. const HtmlWebpackPlugin=require('html-webpack-plugin');
    4. module.exports = {
    5. entry: {
    6. vender:['./src/index.js','./src/common.js'],// 入口文件命名
    7. index:'./src/index.js',
    8. my:'./src/my.js'
    9. }, // 打包入口
    10. output: {
    11. path: __dirname + '/dist', // 输出路径
    12. filename: "[name].[hash:8].js", // 输出文件名,按entry命名输出文件
    13. assetModuleFilename: "imgs/[name].[hash:8].[ext]"
    14. },
    15. optimization:{
    16. minimizer:[
    17. new opimizeCss()
    18. ]
    19. },
    20. mode: "production",// 打包环境设置 production 和 development
    21. module: {
    22. rules: [ // 其中包含各种loader的使用规则
    23. {
    24. test: /\.css$/,
    25. use: [
    26. {
    27. loader:miniCssExtractPlugin.loader,
    28. },
    29. 'css-loader', // 解析css
    30. ]
    31. },
    32. {
    33. test: /\.scss$/,
    34. use: [
    35. {
    36. loader:miniCssExtractPlugin.loader,
    37. },
    38. 'css-loader', // 解析css
    39. 'sass-loader'
    40. ]
    41. },
    42. {
    43. test: /\.(png|jpg|gif|svg|jpeg)$/,
    44. type: "asset/resource",
    45. generator: {
    46. filename: 'imgs/[name].[hash:8].[ext]', //打包后的图片名称name是图片名,[hash:8]是随机8位的hash值 [ext]指图片格式
    47. }
    48. }
    49. ]
    50. },
    51. devServer: {
    52. port: 8080 //端口号
    53. },
    54. plugins: [
    55. new miniCssExtractPlugin({
    56. filename:'[name].css' //输出的css文件名,放置在dist目录下
    57. }),
    58. new HtmlWebpackPlugin({
    59. // 以根目录中的index.html文件作为模板来自动生成dist/index.html文件
    60. // 注意,这里是相对根目录而言的,因为脚本的上下文是在根目录下
    61. template: "./index.html", // 打包的html文件
    62. inject: 'body', // 脚本注入的位置,可以是head, body,或者为 false默认
    63. filename: "index.html", // 打包后的文件名
    64. chunks: ['main'], //引入指定js文件
    65. minify: {
    66. collapseWhitespace: true,
    67. removeComments: true
    68. }
    69. }),
    70. new HtmlWebpackPlugin({
    71. // 以根目录中的index.html文件作为模板来自动生成dist/index.html文件
    72. // 注意,这里是相对根目录而言的,因为脚本的上下文是在根目录下
    73. template: "./my.html", // 打包的html文件
    74. inject: 'body', // 脚本注入的位置,可以是head, body,或者为 false默认
    75. filename: "my.html", // 打包后的文件名
    76. chunks: ['common','my'], //引入指定js文件
    77. minify: {
    78. collapseWhitespace: true,
    79. removeComments: true
    80. }
    81. })
    82. ],
    83. watch: true // 监听文件改动并自动打包
    84. };
  12. 打包前清理dist目录

    npm i -D clean-webpack-plugin 安装插件,把插件加入到web.config.js中。

    1. const {CleanWebpackPlugin} = require('clean-webpack-plugin')
    2. plugins: [
    3. new CleanWebpackPlugin(),
    4. new miniCssExtractPlugin({...})
    5. ]
  13. webpack开发环境配置

    3我们可以使用webpack-dev-server开发服务,这样我们就能通过 localhost:8080 启动一个 express 静态资源 web 服务器,并且会以监听模式自动运行 webpack,在浏览器打开 http://localhost:8080/http://localhost:8080/webpack-dev-server/ 可以浏览项目中的页面和编译后的资源输出,并且通过一个 socket.io 服务实时监听它们的变化并自动刷新页面。

    1. 安装
    1. cnpm install -D webpack-dev-server
    1. 在web.config.js中添加服务器配置:
    1. devServer: {
    2. port: 8080 //端口号
    3. },
    1. 启动服务,此时将会启动一个本地服务器,用http://localhost:8080访问。此时会把文件打包,放入内存中,而非放在目录。
      webpack serve --mode development
    2. 把该命令配置到npm命令中
    1. "scripts": {
    2. "test": "echo \"Error: no test specified\" && exit 1",
    3. "build": "webpack",
    4. "dev": "webpack serve --mode development"
    5. }

    npm run dev 启动

0

Copyright (C) 2021-2026 98社区 All Rights Reserved 蜀ICP备20012692号-3