webpack基础配置详解

webpack 基本配置

  1. webpack && webpack-cli

安装:npm i webpack webpack-cli -D
描述:webpack核心模块javascript

  1. webpack-dev-server

安装:npm i webpack-dev-server -D
描述:此安装包,安装webpack本地服务css

Webpack Dev Server 本地服务

  1. webpack-dev-server 基础配置

安装:npm i webpack-dev-server -D
描述: 本地开发服务html

module.exports={
  devServer:{
    port:8088, //端口
    hot:true,//是否热更新
    // 服务器将从哪一个目录去查找内容文件
    contentBase:path.resovle(__dirname,'dist'),
  }
}
复制代码
  1. webpack-dev-server 跨域代理

一、直接使用代理
二、删除一些自定义的路径
三、设置多个代理
四、对https网址转发设置 secure:false
五、本身设置mock数据(设置中间件), before()和after()vue

module.exports={
  devSever:{
     // 1.直接使用后台接口名 后台:/api/user 请求: /api/user
    proxy:{
      "/api":"http://192.168.1.54:8001",
    },

    // 2.本身添加“api”并删除 后台:/user 请求: /api/user
    proxy:{
      "/api":{
        target:"http://192.168.1.54:8001",
        pathRewrite:{ //重写路径,将“/api”删除
          "/api":""
        }
      },
    }

    //3.多个代理到一个
    proxy:[
      {
        context: ["/api", "/pps", "/login"],
        target: 'http://192.168.1.54:8001',
        changeOrigin: true,
        //若是须要转发的网站是支持 https 的,那么须要增长secure=false,来防止转发失败
        secure: false,
      }
    ],
  // 中间件
    before(app){
      app.get("/user",(req,res)=>{
        res.json({"name":"xie"})
      })
    }
  }
}
复制代码

html 处理

  1. html-webpack-plugin

安装:npm i html-webpack-plugin -D
描述:此插件将html文件输出在输出文件夹中。主要参数具体解释java

const HtmlWebpackPlugin = require("html-webpack-plugin ")
module.exports={
  plugins:[
    new HtmlWebpackPlugin({
      // html模板,能够是 html, jade, ejs, hbs等,必须安装对应的 loader
      template:"./index.html" ,
      filename: "index.html",
      //生成一个icon图标
      favicon: "./favicon.ico",
      //hash值
      hash: true,
      // 使用的代码块,用于多文件打包
      chunks:["home","other"],
      //设置页面的title
      title: 'webpackdemo'
      //minify压缩
      minify: {
        //是否对大小写敏感,默认false
        caseSensitive: true,

        //是否简写boolean格式的属性
        //如:disabled="disabled" 简写为disabled 默认false
        collapseBooleanAttributes: true,

        //是否去除空格,默认false
        collapseWhitespace: true,

        //是否压缩html里的css(使用clean-css进行的压缩) 默认值false;
        minifyCSS: true,

        //是否压缩html里的js(使用uglify-js进行的压缩)
        minifyJS: true,

        //Prevents the escaping of the values of attributes
        preventAttributesEscaping: true,

        //是否移除属性的引号 默认false
        removeAttributeQuotes: true,

        //是否移除注释 默认false
        removeComments: true,

        //从脚本和样式删除的注释 默认false
        removeCommentsFromCDATA: true,

        //是否删除空属性,默认false
        removeEmptyAttributes: true,

        // 若开启此项,生成的html中没有 body 和 head,html也未闭合
        removeOptionalTags: false,

        //删除多余的属性
        removeRedundantAttributes: true,

        //删除script的类型属性
        //在h5下面script的type默认值:text/javascript 默认值false
        removeScriptTypeAttributes: true,

        //删除style的类型属性, type="text/css" 同上
        removeStyleLinkTypeAttributes: true,

        //使用短的文档类型,默认false
        useShortDoctype: true,
      }
    })
  ]
}
复制代码
  1. 使用模板引擎 ejs

安装:npm i html-loader ejs ejs-html-laoder -D
描述:一、安装html-loader , 将html中的文件进行解析
二、安装ejs、ejs-html-laoder对ejs模板进行解析node

//webpack.config.js
module.exports={
  plugins:[
    new HtmlWebpackPlugin({
      template: './index.ejs', // ejs模板
      filename: "index.html",
    }),
  ],
  module:{
    rules:[
      //处理ejs文件
      {
        test: /\.ejs$/,
        use: ['html-loader', 'ejs-html-loader', ]
      }
    ]
  }
}
复制代码
  1. 多页面处理 glob

安装:npm i glob -D
描述:一、插件,匹配解析当前文档目录
二、多页面DEMO:MultipleDemoreact

const glob = require('glob'); 

let setMAP = () => {
  const entry = {}; 
  const HtmlWebpackPlugins = []; 
  //获取当前目录下匹配 "./src/*/index.js" 的文件目录
  const entryFiles = glob.sync(path.join(__dirname, "./src/*/index.js")); 
  entryFiles.forEach(v => {
    const Match = v.match(/src\/(.*)\/index\.js/);
    const pageName = Match && Match[1];
    entry[pageName] = v; //设置entry
    //设置多个html插件
    HtmlWebpackPlugins.push(
      new HtmlWebpackPlugin({
        template: v.replace('index.js', 'index.html'),
        filename: `${pageName}/${pageName}.html` ,
        chunks: [pageName],
        favicon: path.resolve(__dirname, "favicon.ico"), //生成一个icon图标
      })
    );
  })
  return {
    entry,
    HtmlWebpackPlugins
  }
}
const {entry, HtmlWebpackPlugins} = setMAP(); 

module.exports={
  entry:entry, 
  plugins:[....].contact(HtmlWebpackPlugins)
}
复制代码

css 处理

  1. css-loader

安装:npm i css-loader -D
描述:一、此loader 对 css 中的 @import进行处理
二、内部集成了 cssnanojquery

//js中内联处理
import css from 'css-loader!./css/index.css';
console.log(css);
复制代码
  1. mini-css-extract-plugin (经常使用)

安装:npm i mini-css-extract-plugin -D
描述:一、插件, 将全部的css样式打包在一个文件中,经过 link引入。
二、在loader 中使用 MiniCssExtractPlugin.loaderwebpack

  1. style-loader (可选)

安装:npm i style-loader -D
描述:一、此loader 将css插入到html中
二、与 mini-css-extract-plugin 不能共用git

  1. postcss-loader && autoprefixer

安装:npm i postcss-loader autoprefixer -D
描述:一、此插件和loader是自动给css样式添加浏览器前缀。
二、在webpack.config.js中配置 引入 autoprefixer
三、在package.json文件中配置。
四、在根目录建立 postcss.config.js 文件。
五、配置 package.json 中的browserslist来传递autoprefixer的参数。

// package 内容
{
  ....
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

// postcss.config.js 内容
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}
复制代码

案例:

const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 

module.exports={
  plugins:[
    new MiniCssExtractPlugin({
      filename: "main.[hash:8].css",
      // hash: true
    })
  ]
  module:{
    rules:[{
      test:/\.css$/,
      use:[
        MiniCssExtractPlugin.loader,
        "css-loader",
        {
          //也能够在package.json中引入autoprefixer插件
          loader: "postcss-loader",
          options: {
            plugins: [require('autoprefixer')({
              //传参,将覆盖package.json中的"browserslist"
              //并不推荐这样写。应写在package.json中"browserslist"
              overrideBrowserslist: ["last 2 version"]
            })]
          }
        },
      ]
    }]
  }
}
复制代码
  1. node-sass && sass-loader 、less && less-loader、stylus && stylus-loader

安装:npm i node-sass sass-loader -D
描述:此loader 将scss/less/stylus 进行 =>css 处理
Tips:fast-sass-loader 比 sass-loader快5-10倍

  1. optimize-css-assets-webpack-plugin

安装:npm i optimize-css-assets-webpack-plugin -D
描述:一、此插件是将css代码进行压缩。使用此插件,须要js插件进行js压缩。
二、在 optimization 中写。

optimization: {
    minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
  },
复制代码

JS 处理

  1. @babel/core

安装:npm i @babel/core -D
描述:插件,将es语法转换为经常使用的js语法

  1. babel-loader

安装:npm i babel-loader -D
描述:此loader 是 babel 转换的loader

  1. @babel/preset-env

安装:npm i @babel/preset-env -D
描述:babel 预设环境

  1. @babel/plugin-transform-runtime && @babel/runtime(生产环境)

安装:npm i @babel/plugin-transform-runtime -D
安装:npm i @babel/runtime -S
描述:一、babel插件 , ES代码装换时,能够重复使用Babel注入的帮助程序代码来节省代码。
二、对于实例方法,例如"foobar".includes("foo")只能使用core-js

  1. @babel/runtime-corejs2 || @babel/runtime-corejs3 (生产环境)

安装:npm i @babel/runtime-corejs2 -S
安装:npm i @babel/runtime-corejs3 -S
描述:补充对于实例方法的不支持

["@babel/plugin-transform-runtime", {corejs: 3}]

//babel
{
  test: /\.js$/,
  use: [{
    loader: "babel-loader",
    options: {
      presets: ['@babel/preset-env'],
      plugins: [
        ["@babel/plugin-proposal-decorators", {
          "legacy": true
        }],
        ["@babel/plugin-proposal-class-properties", {
          "loose": true
        }],
        ['@babel/plugin-transform-runtime', {
          corejs: 3
        }]
      ]
    },
    env: { //根据不一样环境配置不一样不一样参数
      production: {
        "presets": ["@babel/preset-env"]
      }
    }
  }],
  include: path.resolve(__dirname, 'src'), // 包含路径
  exclude: /node_modules/ // 排除路径
}
复制代码
  1. @babel/polyfill (生产环境)(babel7.4.0已废弃)(可以使用corejs)

安装:npm i @babel/polyfill -D
描述:babel插件 , 将实例方法进行解析,在babel7.4.0已废弃,可使用第7条corejs

npm install --save @babel/polyfill
// 在index.js中引入便可
require("@babel/polyfill")
复制代码
  1. @babel/plugin-proposal-class-properties

安装:npm i @babel/plugin-proposal-class-properties -D
描述:babel插件 , 对es 中 class 模块进行转换

  1. @babel/plugin-proposal-decorators

安装:npm i @babel/plugin-proposal-decorators -D
描述:babel插件 , 装饰器

module: {
  rules: [
    //babel 转换
    {
      test: /\.js$/,
      use: [{
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env'],
          plugins: [
            ["@babel/plugin-proposal-decorators", {
              "legacy": true
            }],
            ["@babel/plugin-proposal-class-properties", {
              "loose": true
            }]
          ]
        }
      }]
    }
  ]
}
复制代码
  1. eslint && eslint-loader

安装:npm i eslint eslint-loader -D
描述:一、js校验。须要配置文件 .eslintrc.json
二、ESLint 的报错类型包括三种:off、warn和error,分别对应着:0、一、2
三、配置.eslintrc.jsoneslint.org/demo
四、规则说明:中文英文
五、腾讯 Alloy规则:Github

// .eslintrc.json
{
  "extends": ['alloy',], //使用本身安装的规则
  'rules': { //本身配置规则
      // 禁止 console,要用写 eslint disbale
      'no-console': 2,
      // 禁止 debugger,防止上线
      'no-debugger': 2,
  }
}

//webpack.config.js
module: {
  rules: [
    //ESLINT
    {
      test: /\.js$/,
      use: {
        loader: "eslint-loader",
        options: {
          enforce: 'pre'  //pre:以前 , post:以后
        }
      }
    }
  ]
}
// package.json
{
  "name":"",
  "eslintConfig": {
    "extends": [],
    "rules": {
      'no-console': 2,
    },
},
}
复制代码

图片引入打包

  1. file-loader (大图片,必须) && url-loader(图片转化base64)

loader , 对于引入的文件处理

module.exports={
  module:{
    rules:[
      {
        test:/\.(png|jpg|jpeg|gif)$/,
        //当图片小于多少k时,转为base64,不然使用file-loader导出
       // use:'file-loader'
       use:{
         loader:'url-loader',
         options:{
           limit:200*1024 //200k
         }
       }
      }
    ]
  }
}
复制代码
  1. 使用js引入图片
import logo from "./logo.jpg"
  let img = new Image()
  img.src = logo;
 //或者 img.src = require('./logo.jpg');
  document.body.appendChild(img)
复制代码
  1. 使用css引入图片

一、直接引入,由于css-loader会进行转换
二、css中使用 alias配置的参数,须要加上 ~

background:url('./logo.jpg')  => background:url(rquire('./logo.jpg'))
复制代码
  1. 使用html引入图片 html-loader

描述:一、loader,对html中的外部资源(图片等)进行转换

rules:[
  {
    test:/\.html$/,
    use:'html-loader'
  }
]
复制代码

三、htmlcss中使用 alias配置的参数,须要加上 ~

// webpack.config.js
const path = require('path')
module.exports={
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  }
}
//html 
<img src="~@/img/large.png" alt="背景图" />
//css
.bg-img {
    background: url(~@/img/small.png) no-repeat;
}
复制代码

其余资源处理

  1. 字体、富媒体

对于字体、富媒体等静态资源,能够直接使用url-loader或者file-loader进行配置便可

{
    // 文件解析
    test: /\.(eot|woff|ttf|woff2|appcache|mp4|pdf)(\?|$)/,
    loader: 'file-loader',
    query: {
        // 这么多文件,ext不一样,因此须要使用[ext]
        name: 'assets/[name].[hash:7].[ext]'
    }
},
复制代码

打包文件分类

  1. 设置全局路径 publicPath

对于引入的资源(js, css, images等)都将会自动加上 publicPath

module.exports={
  output:{
    filename: "bunlde.[hash:8].js",
    path: path.resolve(__dirname, 'dist'), // 当前目录下的dist
    publicPath:'https://www.baidu.com'
  }
}
复制代码
  1. 设置css打包文件夹名

MiniCssExtractPlugin 插件中filename里加 css/

module.exports={
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/main.[hash:8].css", // 添加css/
    })
  ], 
}
复制代码
  1. 设置图片打包文件夹名

一、在 url-laoder(file-loader)中的options里设置 outputPath
二、也能够单独设置一个publicPath

rules: [
  // 图片引入
  {
    test: /\.(png|jpg|jpeg|gif)$/,
    //当图片小于多少k时,转为base64,不然使用file-loader导出
    // use:'file-loader'
    use: {
      loader: 'url-loader',
      options: {
        limit: 200 * 1024, //200k
        outputPath: "img/",
        // publicPath:"https://xxx.xie.com"
      }
    }
  }
]
复制代码

webpack 小插件

  1. clean-webpack-plugin

安装:npm i clean-webpack-plugin -D
描述:一、在打包时将以前的文件夹清理掉
二、clean-webpack-plugin升级踩坑

const {CleanWebpackPlugin} = require('clean-webpack-plugin') // 新版须要进行解构
module.exports={
  plugins: [
    new CleanWebpackPlugin() //默认不传参数,将会删除output指定的输出文件夹
    //传参
    new CleanWebpackPlugin({
      // 忽略掉不须要删除的文件,至关于exclude,被忽略的文件须要在开头加上 "!"号
      // 数组中必须带有"**/*"通配符,不然dist下的文件都不会被删除
      // 删除指定文件/文件夹 path.resolve(__dirname, 'test6')
      cleanOnceBeforeBuildPatterns: ["**/*", path.resolve(__dirname, 'build'),"!public"]
    })
  ]
}
复制代码
  1. copy-webpack-plugin

安装:npm i copy-webpack-plugin -D
描述:将文件拷贝到新的地方,一般用做将静态资源拷贝到dist文件夹中

const CopyWebpackPlugin = require("copy-webpack-plugin")
module.exports={
  plugins: [
    //里面放置数组,能够填写多个
    // 默认会放到output中指定的输出文件夹
    new CopyWebpackPlugin([{
      from: "./src/vendor",
      to: "vendor"
    }])
  ]
}
复制代码
  1. BannerPlugin

webpack自带插件,将每一个问价中写入版权信息

const webpack = require('webpack')
module.exports={
  plugins: [
    new webpack.BannerPlugin('make 2019 by joannes')
  ]
}
复制代码

resolve 参数

  1. resolve.alias

经常使用,文件名缩写

module.exports={
  resolve:{
    alias:{
      //解析路径
      "@":path.resolve(__dirname, 'src')
    }
  }
}
复制代码
  1. resolve.extensions

帮助 Webpack 解析扩展名的配置,默认值:['.wasm', '.mjs', '.js', '.json']

module.exports = {
  resolve: {
      extensions: ['.js', '.json', '.css']
  }
}; 
复制代码
  1. 其余参数
resolve.mainFields: 入口字段  
resolve.mainFiles:解析目录时候的默认文件名,默认是index,即查找目录下面的index+resolve.extensions文件  
resolve.modules:查找模块依赖时,默认是node_modules  
resolve.symlinks:是否解析符合连接(软链接,symlink)  
resolve.plugins:添加解析插件,数组格式  
resolve.cachePredicate:是否缓存,支持 boolean 和 functionfunction 传入一个带有 pathrequire 的对象,必须返回 boolean 值。 复制代码

区分不一样环境

  1. process.env.NODE_ENV

一、设置mode将会默认设置 process.env.NODE_ENV

module.exports={
  mode:'production', // process.env.NODE_ENV=production
  mode:'development' // process.env.NODE_ENV=development
}
复制代码

二、cross-env 设置 process.evn.NODE_ENV
安装: npm i cross-env -D

// package.json
{
  "scripts": {
      "build": "cross-env NODE_ENV=production webpack --config webpack.config.js"
  }
}
复制代码
  1. 设置环境变量, webpack.DefinePlugin
new webpack.DefinePlugin({
    ENV: JSON.stringify('dev')
  })
复制代码
  1. 设置不一样开发环境config webpack-merge

安装:npm i webpack-merge -D
描述:一、安装 webpack-merge
二、设置一个公共的参数,例如:webpack.base.js
三、分别设置不一样环境的参数,例如:webapck.prod.js,webpack.dev.js
四、在不一样的环境中引入公共参数和webpakc-merge
五、在package.json中设置不一样的启动命令

//package.json
"scripts": {
  "build": "webpack --progress --config webpack.prod.js", 
  "dev": "webpack-dev-server --progress --config webpack.dev.js"
}
// webpack.prod.js
let {smart} = require('webpack-merge')
let base = require("./webpack.base.js")
module.exports = smart(base, {
  mode: "production", 
})
复制代码

全局变量引入(jquery为例)

默认已经经过npm安装了jQuery

  1. import $ from "jquery"

在须要的js文件中直接引入, 可是不能够用 window.$

  1. expose-loader (生产环境)

安装:npm i expose-loader -S
描述:一、暴露全局的loader
二、pre: 前置 , normal: 正常 , expose-loader: 内联 , post: 后置

//使用一:在文件中使用
import $ from "expose-loader?$!jquery"

//使用二:在webpack.config中配置
module:{
  rules:[
    {
      test:require.resovle('jquery'), //匹配引入jQuery
      user:"expose-loader?$"
    }
  ]
},
import $ from "jquery" 
复制代码
  1. webpack.ProvidePlugin

webpack自带插件,将 $ 注入到每一个模块中

//在webpack.config中配置
const webpack = require('webpack')
module.exports={
  plugins:[
   new webpack.ProvidePlguin({
     $:'jquery'
   })
  ]
}
复制代码
  1. externals 忽略引入

忽略引入,不进行打包, jquery已经经过cdn引入了

module.exports={
  externals:{
    jquery:'$'
  }
}
复制代码

devtool 调试代码

  1. source-map

源码映射,单独生成一个sourcemap文件,报错时会标识当前报错的列和行

module.exports={
  entry:'', 
  devtool:"source-map"
}
复制代码
  1. eval-source-map

源码映射,不会产生单独文件,报错时会标识当前报错的列和行

module.exports={
  entry:'', 
  devtool:"eval-source-map"
}
复制代码
  1. cheap-module-source-map

源码映射,单独生成一个sourcemap文件,报错时不会标识当前报错的列和行

module.exports={
  entry:'', 
  devtool:"cheap-module-source-map"
}
复制代码
  1. cheap-module-eval-source-map

源码映射,不会产生单独文件,报错时不会标识当前报错的列和行

module.exports={
  entry:'', 
  devtool:"cheap-module-eval-source-map"
}
复制代码

watch 实时监控打包

  1. watch

将watch设置为 true时,将会实时监控文件

  1. watchOptions

设置watch相关参数

module.exports={
  entry:'', 
  watch:true, 
  watchOptions:{
    poll:1000, // 每秒问我 1000 次
    aggregateTimeout:500, // 防抖
    ingored: /node_modules/  //不须要监控的文件
  }
}
复制代码

webpack优化 -- 体积优化

  1. javascript压缩
    1.一、terser-webpack-plugin

    安装:npm i terser-webpack-plugin -D
    描述:webpack官方维护的js压缩插件

    const TerserPlugin = require('terser-webpack-plugin');
    module.exports = {
        optimization: {
            minimizer: [
              new TerserPlugin({
                parallel: true,  // 多线程
                // 使用 cache,加快二次构建速度
                cache: true,
                terserOptions: {
                    comments: false,
                    compress: {
                        // 删除无用的代码
                        unused: true,
                        // 删掉 debugger
                        drop_debugger: true, 
                        // 移除 console
                        drop_console: true, 
                        // 移除无用的代码
                        dead_code: true 
                    }
                }
              });
            ]
        }
    };
    复制代码
    1.二、Scope Hoisting

    描述:一、做用域提高。webpack分析模块关系,尽量把模块放到一个函数中
    二、致使打包的文件体积比较大

    // webpack.config.js
      module.exports = {
          optimization: {
              concatenateModules: true //设置
          }
      };
    复制代码
  2. CSS体积优化
    2.一、mini-css-extract-plugin

    安装:npm i mini-css-extract-plugin -D
    描述:将css打包成一个文件再引入

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    module.exports = {
      plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[name].[contenthash:8].css'
        })
      ],
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader'
            ]
          }
        ]
      }
    };
    复制代码
    2.二、optimize-css-assets-webpack-plugin

    安装:npm i optimize-css-assets-webpack-plugin -D
    描述:css压缩插件。使用的是cssnano引擎

    // webpack.config.js
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    module.exports = {
      optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
      }
    };
    复制代码
  3. 图片资源优化

一、使用file-loader或者url-loader
二、参考上面的图片引入

webpack优化 -- 拆分代码

  1. splitChunks常见配置

一、使用optimization 中的 splitChunks
二、详细解释地址

module.exports = {
    // ...
    optimization: {
        splitChunks: {
            chunks: 'async', // 三选一: "initial" | "all" | "async" (默认)
            minSize: 30000, // 最小尺寸,30K,development 下是10k
            maxSize: 0, // 文件的最大尺寸,0为不限制
            minChunks: 1, // 默认1,被提取的一个模块至少须要在几个 chunk 中被引用
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/, // 正则规则,若是符合就提取 chunk
                    priority: -10 // 缓存组优先级,当一个模块可能属于多个 chunkGroup,这里是优先级
                },
                default: {
                    minChunks: 2,
                    priority: -20, // 优先级
                    reuseExistingChunk: true // 若是该chunk包含的modules都已经另外一个被分割的chunk中存在,那么直接引用已存在的chunk,不会再从新产生一个
                }
            }
        }
    }
};
复制代码
  1. cacheGroups缓存组

一、splitChunks的配置项都做用于cacheGroup上的,默认有两个cacheGroup:vendorsdefault 二、独有的配置项:test(匹配规则)、priority(优先级)和reuseExistingChunk (复用)

webpack优化 -- 速度优化

  1. 减小查找过程
    1.一、resolve.alias

    别名,快速查找

    module.exports={
      resolve:{
        alias:{
          "@":path.resolve(__dirname,'src')
        },
        extensions:['js','json','vue']
      }
    }
    复制代码

    1.二、resolve.extensions

    一、优先查找,将优先查找定义后缀的文件
    二、或者引入文件带上后缀名

    1.三、noParse

    一、排除不须要解析的模块 二、或者引入文件带上后缀名

    module.exports={
      module:{
        noParse: /node_modules\/(jquey\.js)/;
        rules: [
          {
            // test 使用正则
            test: /\.js$/,
            loader: 'babel-loader',
            // 排除路径使用数组
            exclude: [path.resolve(__dirname, './node_modules')],
            // 查找路径使用数组
            include: [path.resolve(__dirname, './src')]
          }
        ];
      },
    }
    复制代码

    1.四、rules配置

    一、只在 test 和 文件名匹配中使用正则表达式
    二、在 include 和 exclude 中使用绝对路径数组;
    三、尽可能避免 exclude,更倾向于使用 include

  2. happypack 多线程打包

安装:npm i happypack -D
描述:happypack插件 ,多线程打包

const Happypack = require('happypack')
module.exports = {
  plugins: [
    new Happypack({
      id: 'js',
      use: [{
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env'],
          plugins: [
            ["@babel/plugin-transform-runtime", {
              corejs: 3
            }]
          ]
        }
      }]
    })
  ], 
  module: {
    // css一样适用
    rules: [{
      test: /\.js$/,
      use: "Happypack/loader?id=js",
      exclude: /node_modules/
    }]
  }
}
复制代码
  1. webpack.DllPlugin 来预先编译
    3.一、DLLPlugin

    一、须要单独设置一个独立的webpack配置文件.例:webpack.config.dll.js

    // webpack.config.dll.js
    const webpack = require('webpack');
    // 这里是第三方依赖库
    const vendors = ['react', 'react-dom'];
    
    module.exports = {
        mode: 'production',
        entry: {
            // 定义程序中打包公共文件的入口文件vendor.js
            vendor: vendors
        },
        output: {
            filename: '[name].[chunkhash].js',
            // 这里是使用将 verdor 做为 library 导出,而且指定全局变量名字是[name]_[chunkhash]
            library: '[name]_[chunkhash]'
        },
        plugins: [
            new webpack.DllPlugin({
                // 这里是设置 mainifest.json 路径
                path: 'manifest.json',
                name: '[name]_[chunkhash]',
                context: __dirname
            })
        ]
    };
    复制代码
    3.二、DllReferencePlugin

    webpack.config.js中指定manifest.json的内容

    // webpack.config.js
    const webpack = require('webpack');
    module.exports = {
        output: {
            filename: '[name].[chunkhash].js'
        },
        entry: {
            app: './src/index.js'
        },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                // 这里导入 manifest配置内容
                manifest: require('./manifest.json')
            })
        ]
    };
    复制代码

webpack优化 -- 其余优化

  1. IgnorePlugin

webpack自带插件,设置忽略某项引入

plugins: [
    //忽略引入 ./locale 在moment中
    new webpack.IgnorePlugin(/\.\/locale/,/moment/)
  ], 
  // 能够手动引入所需的语言包
  import "moment/locale/zh-cn"; 
  moment.locale("zh-cn"); 
复制代码
  1. webpack内置优化

一、tree-shaking

使用 import 导入时,在打包时会自动去除没用的代码
require导入是放在一个对象中的,且不会去除代码, 在default中

二、scope-hosting

做用域提高,打包时将多余的变量进行转化

  1. @babel/plugin-syntax-dynamic-import import按需懒加载

安装:npm i @babel/plugin-syntax-dynamic-import -D
描述:babel插件,须要写在babel中

// index.js
let button = document.createElement('button')
button.innerHTML = "name"
button.addEventListener('click', () => {
  import('./loader').then((data) => {
    console.log(data.default)
  })
})
document.body.appendChild(button)

//webpack.config.js
module.exports={
  module: {
    rules: [{
      test: /\.js$/,
      use: {
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env'],
          plugins: [
            ["@babel/plugin-transform-runtime", {
              corejs: 3
            }],
            //引入
            ['@babel/plugin-syntax-dynamic-import']
          ]
        }
      },
      exclude: /node_modules/
    }]
  }
}

复制代码
  1. 热更新 HotModuleReplacementPlugin

webpack自带插件, 须要在本地服务启动 hot:true

module.exports={
  devSever:{
    hot:true
  }, 
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ], 
}
//index.js
import str from "./source"
if(module.hot){
  module.hot.accept('./source', ()=>{
    console.log("文件更新了")
  })
}
复制代码

webpack经常使用插件,附表:Plugins

webpack经常使用loader,附表:Loaders

相关文章
相关标签/搜索