Rodrick

vuePress-theme-reco Rodrick    2022
Rodrick Rodrick

Choose mode

  • dark
  • auto
  • light
Home
Category
  • CS基础
  • 数据库
  • 前端
  • 其他
Tag
About
Timeline
D&T
  • 官方文档

    • Vue
    • Vue3
    • Webpack
    • MDN
    • Node中文网
    • React
    • 小程序
    • FineReport
  • 学习面试

    • 现代JavaScript教程
    • ES6
    • 阿西河
    • LeetCode
    • 牛客网
  • 工具

    • bejson
Contact
  • Github
  • Gitee
author-avatar

Rodrick

62

Article

18

Tag

Home
Category
  • CS基础
  • 数据库
  • 前端
  • 其他
Tag
About
Timeline
D&T
  • 官方文档

    • Vue
    • Vue3
    • Webpack
    • MDN
    • Node中文网
    • React
    • 小程序
    • FineReport
  • 学习面试

    • 现代JavaScript教程
    • ES6
    • 阿西河
    • LeetCode
    • 牛客网
  • 工具

    • bejson
Contact
  • Github
  • Gitee
  • JS

  • CSS

  • 其他

    • HTML面试题整理
    • Web安全策略
    • HTTP缓存
    • 手写题整理
    • Webpack之手把手教你玩loader_plugin
    • Webpack从0到1学会code_splitting
    • Webpack常用记录
    • babel强化

Webpack常用记录

vuePress-theme-reco Rodrick    2022

Webpack常用记录

Rodrick 2021-06-04 Webpack

# 配置

# Entry

  • entry 可以是字符串、数组、对象
  • 如果是 array 类型,则搭配 output.library 配置项使用时,只有数组里的最后一个入口文件的模块会被导出。
  • entry 为对象且多个的时候,会生成多个 chunk,output 需要动态生成 name
  • entry 也可以动态配置
const path = require('path');

module.exports = {
  // JavaScript 执行入口文件
   entry: './index.js',
  // 同步函数
  // entry:()=>{
  //   return './index.js'
  // },
  // 异步函数
  // entry: () => {
  //   return new Promise(resolve => {
  //     resolve('./index.js')
  //   })
  // },
  // 数组、对象
  // entry: ['./index.js','./show.js'],
  // entry: { a: './index.js',b: './show.js'},
  output: {
    // 把所有依赖的模块合并输出到一个 bundle.js 文件
    filename: 'bundle.js',
    // filename: '[name].js',
    // 输出文件都放到 dist 目录下
    path: path.resolve(__dirname, './dist'),
  },
}

# Output

配置如何输出,是一个对象,常用配置项如下

# filename

  1. 静态
filename: 'bundle.js'
  1. 动态 | 变量名 | 含义 | | --- | --- | | id | Chunk 的唯一标识,从0开始 | | name | Chunk 的名称 | | hash | Chunk 的唯一标识的 Hash 值 | | chunkhash | Chunk 内容的 Hash 值 |
filename: '[name].[hash:8].js',

# path

const path = require('path');
path: path.resolve(__dirname, 'dist_[hash]')

# publicPath

filename:'[name]_[chunkhash:8].js'
publicPath: 'https://cdn.example.com/assets/'

使用时:

<script src='https://cdn.example.com/assets/a_12345678.js'></script>

# Module

  • test::命中文件规则,例如 test: /\.scss$/ 、test:[/\.jsx?$/,/\.tsx?$/],
  • use:使用的 Loader,顺序是从右往左,例如 use: ['style-loader', 'css-loader', 'sass-loader']
  • include 、 exclude:用来处理排除和包含,例如 exclude: path.resolve(__dirname, 'node_modules')


如果一个 Loader 需要传入很多个参数的时候,可以使用一个对象,例如

use: [
  {
    loader:'babel-loader',
    options:{
      cacheDirectory:true,
    },
    // enforce:'post' 的含义是把该 Loader 的执行顺序放到最后
    // enforce 的值还可以是 pre,代表把 Loader 的执行顺序放到最前面
    enforce:'post'
  },
  // 省略其它 Loader
]
  • noParse:可以用来忽略一些没采用模块化的文件的解析,比如一些大型库,jQuery 等
// 使用正则表达式
noParse: /jquery|chartjs/

// 使用函数,从 Webpack 3.0.0 开始支持
noParse: (content)=> {
  // content 代表一个模块的文件路径
  // 返回 true or false
  return /jquery|chartjs/.test(content);
}
  • parser:精确到语法层面忽略哪些模块化语法
module: {
  rules: [
    {
      test: /\.js$/,
      use: ['babel-loader'],
      parser: {
      amd: false, // 禁用 AMD
      commonjs: false, // 禁用 CommonJS
      system: false, // 禁用 SystemJS
      harmony: false, // 禁用 ES6 import/export
      requireInclude: false, // 禁用 require.include
      requireEnsure: false, // 禁用 require.ensure
      requireContext: false, // 禁用 require.context
      browserify: false, // 禁用 browserify
      requireJs: false, // 禁用 requirejs
      }
    },
  ]
}

# CSS/LESS/SASS

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 把js中的样式插入head新创建的style标签
          'style-loader',
          // 把commonjs模块加入js中
          'css-loader']
      },
      {
        test: /\.less$/,
        use: [
          // 把js中的样式插入head新创建的style标签
          'style-loader',
          // 把commonjs模块加入js中
          'css-loader',
          'less-loader'
        ]
      }
    ]
  },

# url-loader/html-loader

分别处理文件url引入和html内类似 <img> 标签的资源问题

      {
        test: /\.(png|jpg|gif)$/,
        // 使用一个loader
        loader: 'url-loader',
        options: {
          // 图片小于8kb就用base64减少请求
          limit: 8 * 1024,
          // 定义hash长度和后缀,[ext] 代表原来的后缀名
          name: "[hash:8].[ext]",
        }
      },
      {
        test: /\.html$/,
        // 处理 html 的引入图片等问题
        loader: 'html-loader',
        options: {
          // 关闭html-loader的ES6模块化,否则图片会出现打包完是无效图片
          esModule: false
        }
      }

# babel

  1. 三个包
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
  1. webpack.config.js
 {
   test: /\.js$/,
   exclude: '/node_modules/',
   use: ['babel-loader']
 },
  1. 根目录下 .babelrc

具体配置见官网说明, env 的包包含了新的所有标准。

{
  "plugins": [],
  "presets": [
    ["env"]
  ]
}

# Plugins

插件使用前记得引入

# html-webpack-plugin 打包html

const HtmlWebpackPlugin =require("html-webpack-plugin")

plugins: [
  // 默认创建一个html自动引入打包输出的资源
  new HtmlWebpackPlugin({
    // 以这个为模板,自动引入
    template:'./src/index.html'
  })
],

# mini-css-extract-plugin css提取

以前的 extract-text-webpack-plugin 在新版的 webpack 不支持了

webpack.config.js
Link

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

module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      // 从 .js 文件中提取出来的 .css 文件的名称
      filename: `[name].css`,
    }),
  ]

# uglifyjs-webpack-plugin 压缩js

Link

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

plugins: [
  new UglifyJsPlugin({
    // 是否输出sourceMap
    sourceMap: false,
    // 文件缓存
    cache: false,
    // 多进程构筑
    parallel:true,
    uglifyOptions: {
      // Enable IE8 Support
      ie8:true,
      compress: {
        // 删除所有的 `console` 语句,可以兼容ie浏览器
        drop_console: false,
        // 内嵌定义了但是只用到一次的变量
        collapse_vars: true,
        // 提取出出现多次但是没有定义成变量去引用的静态值
        reduce_vars: true
      },
      output: {
        // 最紧凑的输出
        beautify: false,
        // 删除所有的注释
        comments: false,
      }
    }
  }
                    )
],

# Resolve

用来配置 webpack 寻找文件的方法

# alias

映射一套路径到新的路径下

resolve:{
  alias:{
    components: './src/components/'
  }
}

这样导入 import main from "./src/components/index.js"  就可以写成 import main from "components/index.js"

# DevServer

// 热更新 + source map
"dev": "webpack-dev-server --hot --devtool source-map"

webpack5 使用会报错,网上查看是因为兼容问题,这里是降级的

"devDependencies": {
  "webpack": "^4.43.0",
  "webpack-cli": "^3.3.12",
  "webpack-dev-server": "^3.11.2"
}

webpack5中使用
注意层级是和entry一层

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports = {
  // JavaScript 执行入口文件
  entry: './src/index.js',
  output: {
    // 把所有依赖的模块合并输出到一个 bundle.js 文件
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist'),
  },
  // mode:"production"
  // devServer只会在内存中编译打包,不会输出
  // 运行命令:npx webpack serve
  devServer: {
    // 构建后目录
    contentBase: path.resolve(__dirname, 'dist'),
    // 启动gzip
    compress: true,
    // 端口
    port: 3000,
    // 自动打开浏览器
    open:true,
  }
}

# watch

// watch 可以监听文件变化进行重新打包,通过watchOptions控制打包变化监听
  watch: false, // 是否开始
  watchOptions: { // 监听模式选项
    // 不监听的文件或文件夹,支持正则匹配。默认为空
    ignored: /(node_modules|index.js)/,
    // 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
    // 默认为300ms 
    aggregateTimeout: 5000,
    // 判断文件是否发生变化是不停的去询问系统指定文件有没有变化,默认每隔1000毫秒询问一次
    poll: 1000
  },

# source-map

/**
   * eval:用 eval 语句包裹需要安装的模块;
   * source-map:生成独立的 Source Map 文件;
   * hidden:不在 JavaScript 文件中指出 Source Map 文件所在,这样浏览器就不会自动加载 Source Map;
   * inline:把生成的 Source Map 转换成 base64 格式内嵌在 JavaScript 文件中;
   * cheap:生成的 Source Map 中不会包含列信息,这样计算量更小,输出的 Source Map 文件更小;同时 Loader 输出的 Source Map 不会被采用;
   * module:来自 Loader 的 Source Map 被简单处理成每行一个模块;
   */
  devtool: 'source-map'
欢迎来到 Rodrick
看板娘