webpack记录

webpack 是一种前端资源构建工具,一个静态模块打包器(module bundler)。

  1. 入口(Entry)指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。
  2. 输出(Output)指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。
  3. Loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解JavaScript)
  4. 插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
  5. 模式(Mode)指示 webpack 使用相应模式的配置。

初始化配置

  1. 初始化 package.json输入指令: npm init
  2. 下载并安装 webpack输入指令:
    npm install webpack webpack-cli -g
    npm install webpack webpack-cli -D

编译打包应用

  • 创建文件后
  • 开发环境指令:webpack src/js/index.js -o build/js/built.js --mode=development
  • 生产环境指令:webpack src/js/index.js -o build/js/built.js --mode=production
  • 能够编译打包 js 和 json 文件。 能将 es6 的模块化语法转换成浏览器能识别的语法。
  • 生产环境比开发环境多一个压缩js代码。

开发环境的基本配置

  • 创建文件 webpack.config.js
    webpack配置
// resolve用来拼接绝对路径的方法
const { resolve } = require('path');
module.exports = {
  // webpack配置
  // 入口起点
  entry: './src/index.js',
  // 输出
  output: {
    // 输出文件名
    filename: 'built.js',
    // 输出路径
    // __dirname nodejs的变量,代表当前文件的目录绝对路径
    path: resolve(__dirname, 'build')
  }

loader配置
打包css,less

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

打包html
下载安装 plugin 包
npm install --save-dev html-webpack-plugin

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
  plugins: [
    // 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
    // 需求:需要有结构的HTML文件
    new HtmlWebpackPlugin({
      // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
      template: './src/index.html'
    })
  ],
  mode: 'development'
};

打包图片

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

打包其他资源

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

开发服务器 devServer

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

提取css

 module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          // 'style-loader', 创建style标签,将样式放入
          // 这个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'
};

兼容处理css

module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,//集合css文件
          'css-loader',
          /*
            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')()
              ]
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/built.css'
    })
  ],
  mode: 'development'
};

压缩css

下载 npm ioptimize-css-assets-webpack-plugin -D ,添加调用即刻
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

new OptimizeCssAssetsWebpackPlugin()

js语法检查

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
        }
      }
    ]
  },
  
// eslint-disable-next-line
下一行eslint所有规则都失效,不检查。

兼容性处理

module: {
    rules: [
      /*
        js兼容性处理:babel-loader @babel/core 
          1. 基本js兼容性处理 --> @babel/preset-env
            问题:只能转换基本语法,如promise高级语法不能转换
          2. 全部js兼容性处理 --> @babel/polyfill  直接在js文件引入import '@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'
                }
              }
            ]
          ]
        }
      }

js和html压缩

 plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
      // 压缩html代码
      minify: {
        // 移除空格
        collapseWhitespace: true,
        // 移除注释
        removeComments: true
    })
  ],
  // 生产环境下会自动压缩js代码
  mode: 'production'

HMR

/*
  HMR: hot module replacement 热模块替换 / 模块热替换
    作用:一个模块发生变化,只重新打包这一个模块提升构建速度
      devServer内部添加hot = true
      样式文件:可以使用HMR功能:因为style-loader内部实现了~
      js文件:默认不能使用HMR功能 --> 需要修改js代码,添加支持HMR功能的代码
        注意:HMR功能对js的处理,只能处理非入口js文件的其他文件。
        if (module.hot) {
  // 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
  module.hot.accept('./print.js', function() {
    // 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
    // 会执行后面的回调函数
    print();
  });
}
      html文件: 默认不能使用HMR功能.同时会导致问题:html文件不能热更新了~ (不用做HMR功能)
        解决:修改entry入口,将html文件作为第二个入口文件
        

*/

source-map

source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快

调试更友好  eval-source-map 生产环境:源代码要不要隐藏?必须是外部 source-map 

oneOf
loader只会匹配一个
注意:不能有两个loader处理同一种类型文件

缓存:
兼容js的loader内加入 cacheDirectory: true
开启babel缓存
第二次构建时,会读取之前的缓存

  • 文件资源缓存

  • hash: 每次wepack构建时会生成一个唯一的hash值。
    问题: 因为js和css同时使用一个hash值。
    如果重新打包,会导致所有缓存失效。(可能我却只改动一个文件)

  • chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
    问题: js和css的hash值还是一样的
    因为css是在js中被引入的,所以同属于一个chunk

  • contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样
    –> 让代码上线运行缓存更好使用

tree shaking:去除无用代码减少代码体积

  1. 必须使用ES6模块化
  2. 开启production环境,会自动使用插件处理
  3. 可能会把css / @babel/polyfill (副作用)文件干掉
  4. 在package.json中配置 “sideEffects”: [".css", ".less"]

code split分件打包

1.多入口:有一个入口,最终输出就有一个bundle,可以js添加命名
2.oqtimization插件,可以将node_modules中代码单独打包一个chunk最终输出,
自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk。
3.单入口,同时添加插件通过js代码,让某个文件被单独打包成一个chunk
  import动态导入语法:能将某个文件单独打包,可以添加注释命名。

懒加载和预加载

  • 正常加载可以认为是并行加载(同一时间加载多个文件)
  • 懒加载:当文件需要使用时才加载
  • 预加载 prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源
  • 预加载兼容不好,只有在高版本了浏览器支持

pwa,离线可访问

  1. WorkboxWebpackPlugin插件安装,启动后内部两个设定
  2. eslint不认识 window、navigator全局变量,需要修改package.json中eslintConfig配置
    “env”: {
    “browser”: true // 支持浏览器端全局变量
  3. sw代码必须运行在服务器上

多进程打包
进程启动为600ms左右,进程通信也要时间。
只有工作消耗时间比较长,才需要多进程打包。
thread-loader可以设置进程数

externals

在js文件引入cdn文件jq
externals: {
// 拒绝jQuery被打包进来
jquery: ‘jQuery’
}

dll

  1. 使用dll技术,对某些库(第三方库:jquery、react、vue…)进行单独打包,避免重复打包,
  2. 运行 webpack.dll.js 文件,默认查找 webpack.config.js 配置文件,然后引入并打包,再暴露并输出。
  3. 安装插件webpack.DllReferencePlugin,告诉webpack哪些库不参与打包,同时使用时的名称也得变
  4. 安装插件AddAssetHtmlWebpackPlugin,某个文件打包输出去,并在html中自动引入该资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值