从0基础到大牛-webpack深入浅出超强完整版(二)

你可能只需要这一个教程

webpack小试牛刀 - ES6+ 转 ES5

  • 全局垫片 polyfill

  使用babel,需要下载 babel-loader @babel/core @babel/preset-env
  babel-loader 下载 npm install -D babel-loader @babel/core @babel/preset-env webpack
  配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.exports = {
module: {
rules: [
{
test: /\.js$/, // 正则 匹配规则
exclude: /node_modules/, // 依赖文件已做过处理,无需再处理,节省打包时间
loader: "babel-loader", // 使用的loader
option: { // 配置 option的配置应参照使用的loader配置列表
presets: ["@babel/preset-env" ]
}
}
]
}
};

  打包生成的文件中,ES6语法将会转为ES5语法
  但并不是所有的ES6都可以被转化,ES6中一些内置API和功能(Promise set Map)、Object.assign等无法转化
  如果想要实现上述这些方法,我们需要使用垫片库(polyfill)npm install -D @babel/polyfill
  直接引入垫片库,会将所有方法都加载进来

1
2
3
4
5

import "@babel/polyfill";
const arr = [new Promise(()=>{}),new Promise(()=>{})];

// 此时 Object.assign Set Map等方法也会被打入,生成文件骤然变大

  如何实现按需加载呢?需要配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
module.exports = {
module: {
rules: [
{
rule: /\.js$/,
exclude: /node_modules/,
loader: "@babel-loader",
options: {
presets: [
["@babel/preset-env",{
"useBuiltIns" : "usage",
// usage: 按需加载 页面无需引入"@babel/polyfill"
// entry: 按需加载 页面需手动引入 import "@babel/polyfill"
// 自测时发现 entry比usage打出的包更轻量

"target": { // 目标 针对浏览器版本打包
ie: "9"
}
}]
]
}
}
]
}
};

  • babel的全局配置
      webpack中options的配置可以全部放置到babel全局配置文件中,其作用和用法完全一致。首先我们先将webpack中babel的options清除
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    module.exports = {
    module: {
    rules: [
    {
    rule: /\.js$/,
    exclude: /node_modules/,
    loader: "@babel-loader",
    }
    ]
    }
    };

  根目录下新建babel配置文件: .babelrc 并配置如下(此处注意JSON写法)

1
2
3
4
5
6
7
8
{
"presets" : [["@babel/preset-env",{
"useBuiltIns": "entry",
"targets": {
"chrome": 67
}
}]]
}

  • 局部垫片 transform-runtime

  polyfill是一个全局的垫片,会将方法全部扩展到原型上。如果是开发库或者框架,就需要使用局部垫片。
  下载transform-runtime npm install --save-dev @babel/plugin-transform-runtimenpm install --save @babel/runtime
  .babelrc配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"presets" : ["@babel/preset-env"],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}

  transform-runtime默认按需加载,无需配置
  corejs可取值false,2,3或{ version: 2 | 3, proposals: boolean },默认为false详见文档

  • 更改文件打包地址
1
2
3
4
5
6
7
const path = require("path"); // node
module.exports = {
output:{
filename: '[name].js',
path: path.resolve(__dirname,'dist'), // __dirname为当前文件路径 dist可更改为要打包的路径名 默认dist
}
}
  • 转换TS文件

  webpack支持Typescript打包,需先下载npm install --save-dev typescript ts-loader
  根目录下新建ts配置文件:tsconfig.json 并配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"compilerOptions": {
"module": "es6", // 模块的引入方式 es6|commonjs
"target": "es5", // 目标语法
"allowJs": true // 是否允许JS语法
},
"include": [ // 包含文件列表
"./src/",
"./"
],
"exclude": [ // 不包含的文件
"node_modules"
]
}

  并在webpack配置中新增loader

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
loader: "ts-loader",
exclude: /node_modules/,
}
]
}
};

  TypeSearch类型约束查找地址

  • 图片打包

  下载file-loader npm install file-loader --save-dev
  webpack中新增图片转换的loader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module.exports = {
module : {
rules : [
{
test: /\.(png|jpe?g|gif)/,
use: {
loader: "file-loader",
options:{
name: "[name]-[hash:5].[ext]", // name:图片名 ext:图片后缀名 hash:5 取Hash前5位值 默认文件名为hash:5
outputPath: "images/" // 输出文件夹(output.path)下 打包输出地址
}
},
exclude: /node_modules/
}
]
}
}

  注:loader有多种引入写法
  另一个插件url-loader包含file-loader,比file-loader更强大。npm install -D url-loader
  将上述配置file-loader改为url-loader,将不再生成image文件,会自动将图片转为base64位并注入js中。现在我们修改配置,限制转Base64大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
module.exports = {
module : {
rules : [
{
test: /\.(png|jpe?g|gif)/,
use: {
loader: "file-loader",
options:{
name: "[name]-[hash:5].[ext]",
outputPath: "images/",
limit: 1024 * 1 //1024 = 1kb 低于1kb生成base64位,以减少http请求
}
},
exclude: /node_modules/
}
]
}
}