webpack单词

字母 解释 读音
const 常量 kɒnst
path 道路,路径 pɑːθ
require 需要 rɪˈkwaɪər
module 模块;组件;模数 ˈmɒdjuːl
exports 出口商品 eksport
entry 入口 ˈentri
mode 模式 məʊd
development
production
output 输出 ˈaʊtpʊt
resolve 决定 ,分解 rɪˈzɒlv
__dirname 目录名
build 构建 bɪld
filename 文件名 ˈfaɪlneɪm
plugins 插件
config 配置 kən’fɪɡ
rules 规则 ruːlz
test: /.txt$/ 测试
template 模板 ˈtempleɪt
options 选择 ˈɒpʃnz
limit 限制 ˈlɪmɪt
esModule: false, 关闭url-loader的es6模块化,使用commonjs解析
name: ‘[hash:10].[ext]’ [hash:10]取图片的hash的前10位 [ext]取文件原来扩展名
exclude 排除 ɪkˈskluːd
devServer 启动devServer指令为:npx webpack-dev-server
contentBase 基于内容 kɑntent beɪs
compress 压缩 kəmˈpres
port 端口 pɔːt
outputPath: ‘imgs’ 输出路径
browserslist 浏览器列表
collapseWhitespace 移除空格 kəˈlæps 倒塌 Whitespace空白
removeComments 移除注释 rɪˈmuːv移动 kmens评论
minify 压缩html代码 mɪnɪfaɪ
enforce: ‘pre’, 优先执行 ɪnˈfɔːs
hot: true 开启HMR功能
source-map 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
oneOf: 注意:不能有两个配置处理同一种类型文件
cacheDirectory: true 开启babel缓存 第二次构建时,会读取之前的缓存
.then 然后 ðen
catch 抓住 kætʃ
reduce 减少;降低;使处于;把…分解 rɪˈdjuːs
externals 拒绝jQuery被打包进来 ɪkˈstɜːrnlz
html-webpack-plugin 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS) 需求:需要有结构的HTML文件
webpack 用于访问内置插件
mini-css-extract-plugin 对输出的css文件进行重命名 filename: ‘css/built.css’
MiniCssExtractPlugin.loader, 这个loader取代style-loader。作用:提取js中的css成单独文件
optimize-css-assets-webpack-plugin 压缩css
process.env.NODE_ENV = ‘development’; 设置nodejs环境变量
[name]:取文件名
    filename: 'js/[name].[contenthash:10].js',

24

document.getElementById('btn').onclick = function() {
     
  // 懒加载~:当文件需要使用时才加载~
  // 预加载 prefetch:会在使用之前,提前加载js文件 
  // 正常加载可以认为是并行加载(同一时间加载多个文件)  
  // 预加载 prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源
  import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test').then(({ mul }) => {
    console.log(mul(4, 5));
  });

25

const WorkboxWebpackPlugin = require('workbox-webpack-plugin');

/*
  PWA: 渐进式网络开发应用程序(离线可访问)
    workbox --> workbox-webpack-plugin
*/

new WorkboxWebpackPlugin.GenerateSW({
     
      /*
        1. 帮助serviceworker快速启动
        2. 删除旧的 serviceworker

        生成一个 serviceworker 配置文件~
      */
      clientsClaim: true,
      skipWaiting: true
    })
test: /.less$/,
style-loader
css-loader
less-loader
test: /.(jpg png
loader: ‘url-loader’, 问题:默认处理不了html中img图片 处理图片资源
test: /.html$/,
loader: ‘html-loader’ 处理html文件的img图片(负责引入img,从而能被url-loader进行处理)
exclude: /.(css、js、html、less)$/, loader: ‘file-loader’, options: { name: ‘[hash:10].[ext]’ // 排除css/js/html资源 // 打包其他资源(除了html/js/css资源以外的资源)
loader: ‘eslint-loader’, 语法检查12
loader: ‘babel-loader’, js兼容性处理:babel-loader @babel/core

启动devServer

// 开发服务器 devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
  // 特点:只会在内存中编译打包,不会有任何输出
  // 启动devServer指令为:npx webpack-dev-server
  devServer: {
     
    // 项目构建后路径
    contentBase: resolve(__dirname, 'build'),
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 3000,
    // 自动打开浏览器
    open: true
css兼容性处理:postcss --> postcss-loader postcss-preset-env

            帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式

            "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"
              ]
            }
          */
          // 使用loader的默认配置
          // 'postcss-loader',
          // 修改loader的配置
          {
     
            loader: 'postcss-loader',
            options: {
     
              ident: 'postcss',
              plugins: () => [
                // postcss的插件
                require('postcss-preset-env')()
              ]
            }

语法检查

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
        }
      }
    ]
  },

js兼容性处理

module: {
     
    rules: [
      /*
        js兼容性处理:babel-loader @babel/core 
          1. 基本js兼容性处理 --> @babel/preset-env
            问题:只能转换基本语法,如promise高级语法不能转换
          2. 全部js兼容性处理 --> @babel/polyfill  
            问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了~
          3. 需要做兼容性处理的就做:按需加载  --> 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'
                }
              }
            ]
          ]
        }
      }
    ]
  },

压缩html代码15

 plugins: [
    new HtmlWebpackPlugin({
     
      template: './src/index.html',
      // 压缩html代码
      minify: {
     
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
      }
    })
  ],

source-map

source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)

    [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

    source-map:外部
      错误代码准确信息 和 源代码的错误位置
    inline-source-map:内联
      只生成一个内联source-map
      错误代码准确信息 和 源代码的错误位置
    hidden-source-map:外部
      错误代码错误原因,但是没有错误位置
      不能追踪源代码错误,只能提示到构建后代码的错误位置
    eval-source-map:内联
      每一个文件都生成对应的source-map,都在eval
      错误代码准确信息 和 源代码的错误位置
    nosources-source-map:外部
      错误代码准确信息, 但是没有任何源代码信息
    cheap-source-map:外部
      错误代码准确信息 和 源代码的错误位置 
      只能精确的行
    cheap-module-source-map:外部
      错误代码准确信息 和 源代码的错误位置 
      module会将loader的source map加入

    内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快

    开发环境:速度快,调试更友好
      速度快(eval>inline>cheap>...)
        eval-cheap-souce-map
        eval-source-map
      调试更友好  
        souce-map
        cheap-module-souce-map
        cheap-souce-map

      --> eval-source-map  / eval-cheap-module-souce-map

    生产环境:源代码要不要隐藏? 调试要不要更友好
      内联会让代码体积变大,所以在生产环境不用内联
      nosources-source-map 全部隐藏
      hidden-source-map 只隐藏源代码,会提示构建后代码错误信息

      --> source-map / cheap-module-souce-map

启动服务器指令

/*
  服务器代码
  启动服务器指令:
    npm i nodemon -g
    nodemon server.js

    node server.js
  访问服务器地址:
    http://localhost:3000

*/
const express = require('express');

const app = express();
// express.static向外暴露静态资源
// maxAge 资源缓存的最大时间,单位ms
app.use(express.static('build', {
      maxAge: 1000 * 3600 }));

app.listen(3000);


const {
      resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

/*
  缓存:
    babel缓存
      cacheDirectory: true
      --> 让第二次打包构建速度更快
    文件资源缓存
      hash: 每次wepack构建时会生成一个唯一的hash值。
        问题: 因为js和css同时使用一个hash值。
          如果重新打包,会导致所有缓存失效。(可能我却只改动一个文件)
      chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
        问题: js和css的hash值还是一样的
          因为css是在js中被引入的,所以同属于一个chunk
      contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样    
      --> 让代码上线运行缓存更好使用
*/

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';

// 复用loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader',
  {
     
    // 还需要在package.json中定义browserslist
    loader: 'postcss-loader',
    options: {
     
      ident: 'postcss',
      plugins: () => [require('postcss-preset-env')()]
    }
  }
];

module.exports = {
     
  entry: './src/js/index.js',
  output: {
     
    filename: 'js/built.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
     
    rules: [
      {
     
        // 在package.json中eslintConfig --> airbnb
        test: /\.js$/,
        exclude: /node_modules/,
        // 优先执行
        enforce: 'pre',
        loader: 'eslint-loader',
        options: {
     
          fix: true
        }
      },
      {
     
        // 以下loader只会匹配一个
        // 注意:不能有两个配置处理同一种类型文件
        oneOf: [
          {
     
            test: /\.css$/,
            use: [...commonCssLoader]
          },
          {
     
            test: /\.less$/,
            use: [...commonCssLoader, 'less-loader']
          },
          /*
            正常来讲,一个文件只能被一个loader处理。
            当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
              先执行eslint 在执行babel
          */
          {
     
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
     
              presets: [
                [
                  '@babel/preset-env',
                  {
     
                    useBuiltIns: 'usage',
                    corejs: {
      version: 3 },
                    targets: {
     
                      chrome: '60',
                      firefox: '50'
                    }
                  }
                ]
              ],
              // 开启babel缓存
              // 第二次构建时,会读取之前的缓存
              cacheDirectory: true
            }
          },
          {
     
            test: /\.(jpg|png|gif)/,
            loader: 'url-loader',
            options: {
     
              limit: 8 * 1024,
              name: '[hash:10].[ext]',
              outputPath: 'imgs',
              esModule: false
            }
          },
          {
     
            test: /\.html$/,
            loader: 'html-loader'
          },
          {
     
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: 'file-loader',
            options: {
     
              outputPath: 'media'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
     
      filename: 'css/built.[contenthash:10].css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
     
      template: './src/index.html',
      minify: {
     
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  mode: 'production',
  devtool: 'source-map'
};

tree shaking:去除无用代码

tree shaking:去除无用代码
    前提:1. 必须使用ES6模块化  2. 开启production环境
    作用: 减少代码体积

    在package.json中配置 
      "sideEffects": false 所有代码都没有副作用(都可以进行tree shaking)
        问题:可能会把css / @babel/polyfill (副作用)文件干掉
      "sideEffects": ["*.css", "*.less"]

多入口23-1

entry: {
     
    // 多入口:有一个入口,最终输出就有一个bundle
    index: './src/js/index.js',
    test: './src/js/test.js'
  },

自动分析多入口chunk中23-2


    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
  */
  optimization: {
     
    splitChunks: {
     
      chunks: 'all'
    }
  },

26多线程

1. eslint不认识 window、navigator全局变量
    解决:需要修改package.json中eslintConfig配置
      "env": {
     
        "browser": true // 支持浏览器端全局变量
      }
   2. sw代码必须运行在服务器上
      --> nodejs
      -->
        npm i serve -g
        serve -s build 启动服务器,将build目录下所有资源作为静态资源暴露出去
*/
// 注册serviceWorker
// 处理兼容性问题
if ('serviceWorker' in navigator) {
     
  window.addEventListener('load', () => {
     
    navigator.serviceWorker
      .register('/service-worker.js')
      .then(() => {
     
        console.log('sw注册成功了~');
      })
      .catch(() => {
     
        console.log('sw注册失败了~');
      });
  });
 externals: {
     
    // 拒绝jQuery被打包进来
    jquery: 'jQuery'
  }

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'
        }



entry: {
     
    index: ['./src/index.js', './src/count.js'], 
    add: './src/add.js'
  },

output

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'
  },

module

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: []
      }
    ]
  },

resolve配置解析模块路径别名

mode: 'development',
  // 解析模块的规则
  resolve: {
     
    // 配置解析模块路径别名: 优点简写路径 缺点路径没有提示
    alias: {
     
      $css: resolve(__dirname, 'src/css')
    },
    // 配置省略文件路径的后缀名
    extensions: ['.js', '.json', '.jsx', '.css'],
    // 告诉 webpack 解析模块是去找哪个目录
    modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
  }

devServer运行代码的目录

devServer: {
     
    // 运行代码的目录
    contentBase: resolve(__dirname, 'build'),
    // 监视 contentBase 目录下的所有文件,一旦文件变化就会 reload
    watchContentBase: true,
    watchOptions: {
     
      // 忽略文件
      ignored: /node_modules/
    },
    // 启动gzip压缩
    compress: true,
    // 端口号
    port: 5000,
    // 域名
    host: 'localhost',
    // 自动打开浏览器
    open: true,
    // 开启HMR功能
    hot: true,
    // 不要显示启动服务器日志信息
    clientLogLevel: 'none',
    // 除了一些基本启动信息以外,其他内容都不要显示
    quiet: true,
    // 如果出错了,不要全屏提示~
    overlay: false,
    // 服务器代理 --> 解决开发环境跨域问题
    proxy: {
     
      // 一旦devServer(5000)服务器接受到 /api/xxx 的请求,就会把请求转发到另外一个服务器(3000)
      '/api': {
     
        target: 'http://localhost:3000',
        // 发送请求时,请求路径重写:将 /api/xxx --> /xxx (去掉/api)
        pathRewrite: {
     
          '^/api': ''
        }
      }
    }
  }
optimization: {
     
    splitChunks: {
     
      chunks: 'all'
      // 默认值,可以不写~
      /* minSize: 30 * 1024, // 分割的chunk最小为30kb
      maxSiza: 0, // 最大没有限制
      minChunks: 1, // 要提取的chunk最少被引用1次
      maxAsyncRequests: 5, // 按需加载时并行加载的文件的最大数量
      maxInitialRequests: 3, // 入口js文件最大并行请求数量
      automaticNameDelimiter: '~', // 名称连接符
      name: true, // 可以使用命名规则
      cacheGroups: {
     
        // 分割chunk的组
        // node_modules文件会被打包到 vendors 组的chunk中。--> vendors~xxx.js
        // 满足上面的公共规则,如:大小超过30kb,至少被引用一次。
        vendors: {
     
          test: /[\\/]node_modules[\\/]/,
          // 优先级
          priority: -10
        },
        default: {
     
          // 要提取的chunk最少被引用2次
          minChunks: 2,
          // 优先级
          priority: -20,
          // 如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块
          reuseExistingChunk: true
        } 
      }*/
    },
    // 将当前模块的记录其他模块的hash单独打包为一个文件 runtime
    // 解决:修改a文件导致b文件的contenthash变化
    runtimeChunk: {
     
      name: entrypoint => `runtime-${
      entrypoint.name}`
    },
    minimizer: [
      // 配置生产环境的压缩方案:js和css
      new TerserWebpackPlugin({
     
        // 开启缓存
        cache: true,
        // 开启多进程打包
        parallel: true,
        // 启动source-map
        sourceMap: true
      })
    ]
  }

你可能感兴趣的:(webpack)