likes
comments
collection
share

干货满满 webpack配置的详细解析

作者站长头像
站长
· 阅读数 49

所有构建工具都是基于node.js平台运行的~模块化默认采用common.js

webpack 使用的包一般都是开发依赖

  1. 结论

    • webpack 能够编译打包 js 和json 文件
    • 能将es6的模块化语法转换成浏览器能识别的语法
    • 能压缩代码
  1. 问题

    • 不能编译打包css、img 等文件
    • 不能将js 的es6基本语法转化为es5以下语法

1. 初始化配置

  1.1 初始化 package.json-------- 输入指令 npm init 
  1.2 下载安装webpack ------- npm install webpack webpack-cli -g  //全局安装
                             npm install webpack webpack-cli -D  //开发依赖

2.创建配置文件

  1. 创建文件 webpack.config.js

  2. 配置内容如下

    const { resolve } = require('path'); // node 内置核心模块,用来处理路径问题。
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    ​
    module.exports = {
      entry: './src/js/index.js', // 入口文件
      output: { // 输出配置
          filename: 'js/built.js', // 输出文件名
          // __dirname node.js的变量,代表当前文件的目录绝对路径
          path: resolve(__dirname, 'build'),// 输出文件路径配置
         // 所有资源引入公共路径前缀 --> 'imgs/a.jpg' --> './imgs/a.jpg'
          publicPath: './',
      },
      
      mode: 'development', //开发环境 production
      
      //loader的配置
      module:{
        rules:[
          // 不同文件必须配置不同 loader 处
          {
             test:/.css$/,
             // 使用哪些 loader 进行处理
             use:[
               //use数组中loader执行顺序:从右到左,从下到上,依次执行
               // 创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效
              'style-loader',
               // 将 css 文件变成 commonjs 模块加载 js 中,里面内容是样式字符串
               'css-loader'
              ]
          },
          {
            test: /.less$/,
            use: [
            'style-loader',
            'css-loader',
            // 将 less 文件编译成 css 文件
            // 需要下载 less-loader 和 less
            'less-loader'
            ]
          }
        ]
      },
      //详情plugins的配置
      plugins:[
       
      ]
    };
    

3. 打包样式资源

  1. 下载安装 loader

      npm install html-webpack-plugin@3 -D
    
  2. 配置

     //loader的配置
      module:{
        rules:[
          // 不同文件必须配置不同 loader 处
          {
             test:/.css$/,
             // 使用哪些 loader 进行处理
             use:[
               //use数组中loader执行顺序:从右到左,从下到上,依次执行
               // 创建 style 标签,将 js 中的样式资源插入进行,添加到 head 中生效
              'style-loader',
               // 将 css 文件变成 commonjs 模块加载 js 中,里面内容是样式字符串
               'css-loader'
              ]
          },
          {
            test: /.less$/,
            use: [
            'style-loader',
            'css-loader',
            // 将 less 文件编译成 css 文件
            // 需要下载 less-loader 和 less
            'less-loader'
            ]
          }
        ]
      }
    ​
    

4.打包HTML资源

  1. 下载安装 plugin

    npm install html-webpack-plugin@3 -D
    
  2. 配置

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    ​
    plugins: [
        // plugins的配置
        // html-webpack-plugin
        // 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
        // 需求:需要有结构的HTML文件
        new HtmlWebpackPlugin({
          // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
          template: './src/index.html',
          filename:"index.html",//文件输出名
          inject:"body" //<script></script>生成的位置
        })
      ],
    

5.打包图片资源

  1. 下载安装 loader

    npm install html-loader url-loader -D
    
  2. 配置

     module: {
        rules: [
          {
            // 问题:默认处理不了html中img图片
            // 处理图片资源
            test: /.(jpg|png|gif)$/,
            // 使用一个loader
            // 下载 url-loader file-loader
            loader: 'url-loader',
            options: {
              // 图片大小小于8kb,就会被base64处理
              // 优点: 减少请求数量(减轻服务器压力)
              // 缺点:图片体积会更大(文件请求速度更慢)
              limit: 8 * 1024,
              // 问题:因为url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs
              // 解析时会出问题:[object Module]
              // 解决:关闭url-loader的es6模块化,使用commonjs解析
              esModule: false,
              // 给图片进行重命名
              // [hash:10]取图片的hash的前10位
              // [ext]取文件原来扩展名
              name: '[hash:10].[ext]',
              outputPath: 'imgs',//指定输出的文件
            }
          },
          {
            test: /.html$/,
            // 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
            loader: 'html-loader'
          }
        ]
      },
    

6.打包其他资源

如:字体图标

  1. 下载安装包

    npm install file-loader -D
    
  2. 配置

      module: {
        rules: [
          // 打包其他资源(除了html/js/css资源以外的资源)
          {
            // 排除css/js/html资源
            exclude: /.(css|js|html|less)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10].[ext]',
              outputPath: 'media'
            }
          }
        ]
      },
    

7. devserver

  1. 下载安装包

    npm install webpack-dev-server -D
    
  2. 配置

    devserver用于开发环境

     // 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
      // 特点:只会在内存中编译打包,不会有任何输出
      // 启动devServer指令为:npx webpack-dev-server
      devServer: {
        // 项目构建后路径 也就是运行代码的目录
        contentBase: resolve(__dirname, 'build'),
        // 监视 contentBase 目录下的所有文件,一旦文件变化就会重新加载页面
        watchContentBase: true,
        watchOptions: {
          // 忽略文件
          ignored: /node_modules/
        },
        // 启动gzip压缩
        compress: true,
        // 端口号
        port: 3000,
        // 自动打开浏览器
        open: true,
        //域名
        host:"127.0.0.1",// 配置启动ip地址
        // 不要显示启动服务器日志信息
        clientLogLevel: 'none',
        // 除了一些基本启动信息以外,其他内容都不要显示
        quiet: true,
        // 服务器代理 --> 解决开发环境跨域问题
        proxy: {
          // 一旦devServer(5000)服务器接受到 /api/xxx 的请求,就会把请求转发到另外一个服务器(3000) 
          '/api': {
            target: 'http://localhost:3000',
            secure: false,//接受在 HTTPS 上运行且证书无效的后端服务器
            changeOrigin: true,//允许代理
            // 发送请求时,请求路径重写:将 /api/xxx --> /xxx (去掉/api)
            pathRewrite: {
              '^/api': ''
            }
          }
        }
      }
    

8.提取css成单独文件

  1. 下载安装包

    npm install mini-css-extract-plugin -D
    
  2. 配置

    const { resolve } = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    ​
    module.exports = {
      entry: './src/js/index.js',
      output: {
        filename: 'js/built.js',
        path: resolve(__dirname, 'build')
      },
      module: {
        rules: [
          {
            test: /.css$/,
            use: [
              // 创建style标签,将样式放入
              // 'style-loader', 
              // 这个loader取代style-loader。作用:提取js中的css成单独文件
              MiniCssExtractPlugin.loader,
              // 将css文件整合到js文件中
              'css-loader'
            ]
          }
        ]
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html'
        }),
        new MiniCssExtractPlugin({
          // 对输出的css文件进行重命名
          filename: 'css/built.css'
        })
      ],
      mode: 'development'
    };
    

9.css兼容性处理

  1. 下载loader

    npm install postcss-loader postcss-preset-env -D
    
  2. 配置

    // 设置 nodejs 环境变量 
    // process.env.NODE_ENV = 'development';module: {
        rules: [
            {
            test: /.css$/,
            use: [
               MiniCssExtractPlugin.loader,
              'css-loader',
              /*
                css兼容性处理:postcss --> postcss-loader postcss-preset-env
                帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式
              */
              // 使用loader的默认配置
              // 'postcss-loader',
              // 修改loader的配置
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss',
                  plugins: () => [
                    // postcss的插件
                    require('postcss-preset-env')()
                  ]
                }
              }
        ]
    }
    
  3. 修改 package.json

    "browserslist": {
      // 开发环境 --> 设置node环境变量:process.env.NODE_ENV = development
      "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
      ],
      // 生产环境:默认是看生产环境
      "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
      ]
    }
    

10.CSS压缩

  1. 下载安装包

    npm install optimize-css-assets-webpack-plugi -D
    
  2. 配置

    const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
    ​
    plugins: [
      // 需求:需要有结构的HTML文件  
      new HtmlWebpackPlugin({template: './src/index.html'}),
      // 对输出的css文件进行重命名
      new MiniCssExtractPlugin({filename: 'css/built.css'}),
      // 压缩 css
      new OptimizeCssAssetsWebpackPlugin()
    ],
    

11.js语法检查

  1. 下载安装包

    npm install eslint-loader eslint eslint-config-airbnb-base eslint-plugin-i
    
  2. 配置

     module: {
        rules: [
          /*
            语法检查: eslint-loader  eslint
              注意:只检查自己写的源代码,第三方的库是不用检查的
              设置检查规则:
                package.json中eslintConfig中设置~
                  "eslintConfig": {
                    "extends": "airbnb-base"
                  }
                airbnb --> eslint-config-airbnb-base  eslint-plugin-import eslint
          */
          {
            test: /.js$/,
            exclude: /node_modules/,
            loader: 'eslint-loader',
            options: {
              // 自动修复eslint的错误
              fix: true
            }
          }
        ]
      },                                                                                                           
    

12.js 兼容性处理

  1. 下载安装包

    npm install babel-loader @babel/core core-js -D
    
  2. 配置

     module: {
        rules: [
          /*
            js兼容性处理:babel-loader @babel/core 
              需要做兼容性处理的就做:按需加载  --> core-js
          */  
          {
            test: /.js$/,
            exclude: /node_modules/,//排除
            loader: 'babel-loader',
            options: {
              // 预设:指示babel做怎么样的兼容性处理
              presets: [
                [
                  '@babel/preset-env',
                  {
                    // 按需加载
                    useBuiltIns: 'usage',
                    // 指定core-js版本
                    corejs: {
                      version: 3
                    },
                    // 指定兼容性做到哪个版本浏览器
                    targets: {
                      chrome: '60',
                      firefox: '60',
                      ie: '9',
                      safari: '10',
                      edge: '17'
                    }
                  }
                ]
              ]
            }
          }
        ]
      },
    

13.js.压缩

  1. 修改配置

    mode: “production" 会自动压缩js代码

    const { resolve } = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    ​
    module.exports = {
      entry: './src/js/index.js',
      output: {
        filename: 'js/built.js',
        path: resolve(__dirname, 'build')
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html'
        })
      ],
      // 生产环境下会自动压缩js代码
      mode: 'production'
    };
    ​
    

14.HTML压缩

  1. 修改配置

    const { resolve } = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    ​
    module.exports = {
      entry: './src/js/index.js',
      output: {
        filename: 'js/built.js',
        path: resolve(__dirname, 'build')
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
          // 压缩html代码
          minify: {
            // 移除空格
            collapseWhitespace: true,
            // 移除注释
            removeComments: true,
            minifyCSS: true// 压缩内联css
          }
        })
      ],
      mode: 'production'
    };
    ​
    

15.externals

  1. 修改配置

    防止将依赖打包到输出文件中,方便使用CDN链接引用

       const { resolve } = require('path');
       const HtmlWebpackPlugin = require('html-webpack-plugin');
    
       module.exports = {
         entry: './src/js/index.js',
         output: {
           filename: 'js/built.js',
           path: resolve(__dirname, 'build')
         },
         plugins: [
           new HtmlWebpackPlugin({
             template: './src/index.html'
           })
         ],
         mode: 'production',
         externals: {
           // 拒绝jQuery被打包进来
           jquery: 'jQuery'
         }
       };
    
    

16 配置详解

16.1 entry(入口起点)

 entry: 入口起点
    1. string --> './src/index.js'
      单入口
      打包形成一个chunk。 输出一个bundle文件。
      此时chunk的名称默认是 main
    2. array  --> ['./src/index.js', './src/add.js']
      多入口
      所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
        --> 只有在HMR功能中让html热更新生效~
    3. object
      多入口
      有几个入口文件就形成几个chunk,输出几个bundle文件
      此时chunk的名称是 key
​
      --> 特殊用法
        {
          // 所有入口文件最终只会形成一个chunk, 输出出去只有一个bundle文件。
          index: ['./src/index.js', './src/count.js'], 
          // 形成一个chunk,输出一个bundle文件。
          add: './src/add.js'
  }

16.2 output (输出文件)

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
​
module.exports = {
  entry: './src/index.js',
  output: {
    // 文件名称(指定名称+目录)
    filename: 'js/[name].js',
    // 输出文件目录(将来所有资源输出的公共目录)
    path: resolve(__dirname, 'build'),
    // 所有资源引入公共路径前缀 --> 'imgs/a.jpg' --> './imgs/a.jpg'
    publicPath: './',
    chunkFilename: 'js/[name]_chunk.js', // 非入口chunk的名称
    // library: '[name]', // 整个库向外暴露的变量名
    // libraryTarget: 'window' // 变量名添加到哪个上 browser
    // libraryTarget: 'global' // 变量名添加到哪个上 node
    // libraryTarget: 'commonjs'
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'development'
};

16.3 module(模块)

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
​
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'js/[name].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      // loader的配置
      {
        test: /.css$/,
        // 多个loader用use
        use: ['style-loader', 'css-loader']
      },
      {
        test: /.js$/,
        // 排除node_modules下的js文件
        exclude: /node_modules/,
        // 只检查 src 下的js文件
        include: resolve(__dirname, 'src'),
        // 优先执行
        enforce: 'pre',
        // 延后执行
        // enforce: 'post',
        // 单个loader用loader
        loader: 'eslint-loader',
        options: {}
      },
      {
        // 以下配置只会生效一个
        oneOf: []
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'development'
};
​

16.4 (解析模块规则)

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
​
module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/[name].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'development',
  // 解析模块的规则
  resolve: {
    // 配置解析模块路径别名: 优点简写路径 缺点路径没有提示
    alias: {
      $css: resolve(__dirname, 'src/css')
    },
    // 配置省略文件路径的后缀名
    extensions: ['.js', '.json', '.jsx', '.css'],
    // 告诉 webpack 解析模块是去找哪个目录
    modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
  }
};

17.网站图标

  1. 配置

    module.exports = {
      pwa: {
            iconPaths: {
                favicon32: 'dhfavicon.ico',
                favicon16: 'dhfavicon.ico',
                appleTouchIcon: 'dhfavicon.ico',
                maskIcon: 'dhfavicon.ico',
                msTileImage: 'dhfavicon.ico'
            }
        }
    }
    

18.关闭eslint

  1. 项目根目录下创建 vue.config.js

    # vue.config.js
    module.exports = {
      lintOnSave: false
    }
    ​
    # 重启项目
    npm run serve  (yarn serve)
    

19.去掉代码的console.log

  1. 安装插件

    npm install terser-webpack-plugin -D
    
  2. 配置

    const TerserWebpackPlugin = require('terser-webpack-plugin')
    ​
    module.exports = {
       // ...
       optimization: {
        minimizer: [
          // new OptimizeCssAssetsWebpackPlugin(),
          new TerserWebpackPlugin({
            parallel: 4,
            extractComments: true,
            terserOptions: {
              compress: {
                warnings: false,
                drop_console: true,
                drop_debugger: true
              }
            }
          })
        ]
      },
    }
    

陪我看月亮,陪我学习 TypeScript,好吗?

TS+vue3 如何结合打套组合拳

来点不一样的, 怎么玩好LoL (英雄联盟)

转载自:https://juejin.cn/post/7137907671495081991
评论
请登录