webpack一:常用loader和plugin

webpack 默认情况下只能处理 js 模块,如果需要处理其它类型的模块,则需要使用它提供的一些其它功能

  • loaders:webpack 可以使用 loader 来预处理文件,处理非 js 类型的模块,这允许你打包除 JavaScript 之外的任何静态资源。
  • plugins:主要是扩展 webpack 本身的一些功能。插件可以运行在 webpack 的不同阶段(钩子 / 生命周期)。

Loaders

https://webpack.js.org/loaders/

webpack 碰到不识别的模块的时候,webpack 会在配置的 module 中进行该文件解析规则的查找

  • rules 就是我们为不同类型的文件定义的解析规则对应的 loader,它是一个数组
  • 通过 test 选项来匹配需要处理的文件,通常通过正则的方式来匹配文件后缀类型
  • use 针对匹配到文件类型,调用对应的 loader 进行处理
module.exports = {
    module: {
        rules: [
            {
                test: /\.xxx$/,
                use: {
                    loader: 'xxx-loader'
                }
            }
        ]
    }
}

处理js相关

Babel工具集:https://www.babeljs.cn/
提供语法转换和Polyfill 方式添加缺失的特性

高级语法转换

npm install --save-dev babel-loader @babel/core @babel/preset-env
        {
            test: /\.js$/,
            use: [{
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env']
                }
            },
            ]
        }
//打包前代码
const a = () => {
    console.log('a');
}
//打包后代码
eval("var a = function a() {\n  console.log('a');\n};\n\n//# sourceURL=webpack://test/./src/index.js?");

Polyfill 方式添加缺失的特性

注意是需要打包到最终代码包里的

npm install --save @babel/polyfill
//打包前代码
import "@babel/polyfill";
new Promise(()=>{})
//打包后代码包里会包含Promise的polyfill
...polyfill代码
eval("new Promise(function () {});\n\n//# sourceURL=webpack://test/./src/index.js?");

按需引入特性Polyfill

默认会把所有的Polyfill都导入进包里,实际上我们可能只使用了部分特性。
useBuiltIns
entry:需要在入口导入文件,会自动检测按需导入。
usage:不用再在主文件入口引入@babel/polyfill
        {
            test: /\.js$/,
            use: [{
                loader: 'babel-loader',
                options: {
                    presets: [
                        ['@babel/preset-env',
                            {
                                "useBuiltIns": "usage"
                            }
                        ]
                    ]
                }
            },
            ]
        }]
@babel/polyfill默认是安装的2.x版本的core-js,但是js特性一直在新增,如果需要,可以直接安装core-js获得最新的全部poliyfil
npm i core-js
npm i regenerator-runtime

具体使用介绍去github搜索查看。

// polyfill 仅稳定的特性 - ES 和 web 标准:
import "core-js/stable";
import "regenerator-runtime/runtime";

配置项也可以在babel.config.json或者.babelrc(旧版本配置文件名)

也可以用js编写,以动态的生成配置。

{
  "presets": ["@babel/preset-env"]
}

解析jsx

npm install --save-dev @babel/preset-react

babel.config.json

{
    "presets": [
        "@babel/preset-env",
        //配置解析jsx的插件
        "@babel/preset-react"
    ]
}
//打包前代码
let a = <div>jsx</div>
//打包后代码
eval("var a = /*#__PURE__*/React.createElement(\"div\", null, \"jsx\");\n\n//# sourceURL=webpack://test/./src/index.js?");

解析TS

npm install --save-dev @babel/preset-typescript
{
  "presets": ["@babel/preset-typescript"]
}

解析vue

见官网:https://vue-loader.vuejs.org/zh

browserslist定义浏览器目标范围

//可以在package.json添加配置项
  "browserslist": [
    "last 2 version",
    "> 1%"
  ]
 //也可以直接添加一个文件.browserslistrc配置
 last 2 version
 > 1%

处理文件图片相关

file-loader

把识别出的资源模块,移动到指定的输出⽬目录,并且返回这个资源在输出目录的地址(字符串)

npm install --save-dev file-loader
rules: [
    {
        test: /\.(png|jpe?g|gif)$/,
        use: {
            loader: "file-loader",
            options: {
                // [name] 原来资源的名称
                // [ext] 原来资源的后缀
                name: "[name]_[hash].[ext]",
                //打包后的存放位置,相对于打包目标文件夹
                outputPath: "./images",
                // 相对于此config配置的路径,控制打包后文件引入图片的url,需要注意是否匹配。
                publicPath: './images',
            }
        }
    }
]

url-loader

本身也依赖于file-loader

npm i url-loader
        rules: [{
            test: /\.png$/,
            use: {
                loader: 'url-loader',
                options: {
                    //低于2kb的图片转成base64,注意不要设置太大,影响代码体积。
                    limit: 2 * 1024
                }
            }
        }]

image-webpack-loader

可以压缩图片

npm i image-webpack-loader
rules: [{
    test: /\.(gif|png|jpe?g|svg)$/i,
    use: [
        'url-loader',
        'image-webpack-loader',
    ],
}]

处理css相关

css-loader

分析 css 模块之间的关系,并合成⼀个 css,只是生成js字符串,无法实际生效

npm install --save-dev css-loader
rules: [
    {
        test: /\.css$/,
        use: {
            loader: "css-loader",
            options: {
                // 启用/禁用 url() 处理
                url: true,
                // 启用/禁用 @import 处理
                import: true,
                // 启用/禁用 Sourcemap
                sourceMap: false
            }
        }
    }
]

style-loader

css-loader 生成的内容,用 style 标签挂载到⻚面的 head

npm install --save-dev style-loader
rules: [
    {
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
    }
]
同一个任务的 loader 可以同时挂载多个,处理顺序为:从右到左,也就是先通过 css-loader 处理,然后把处理后的 css 字符串交给 style-loader 进行处理
定义多个options可以把数组里元素写成对象模式,
rules: [
    {
        test: /\.css$/,
        use: [
            {
                loader: 'style-loader',
                options: {}
            },
            'css-loader'
        ]
    }
]

mini-css-extract-plugin

提取 CSS 到一个单独的文件中

npm install --save-dev mini-css-extract-plugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    "css-loader"]
            },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css'
        }),
    ]
}

postcss-loader

一个css工具集,可以实现css各种需求

npm i postcss-loader postcss
实现添加前缀,以兼容浏览器。
npm i autoprefixer

增加postcss.config.js文件

module.exports = {
    plugins: [require("autoprefixer")],
};

webpack配置

            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    'css-loader',
                    'postcss-loader'
                ]
            },

测试:

/* 打包前 */
::placeholder {
    color: gray;
  }
/* 打包后 */
::-moz-placeholder {
    color: gray;
  }
:-ms-input-placeholder {
    color: gray;
  }
::placeholder {
    color: gray;
  }  

Plugins

扩展 webpack 本身的一些功能,它们会运行在 webpack 的不同阶段(钩子 / 生命周期)。webpack 自身也是构建于插件系统之上!

HtmlWebpackPlugin

在打包结束后,⾃动生成⼀个 html 文件,并把打包生成的 js 模块引⼊到该 html

npm install --save-dev html-webpack-plugin
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  plugins: [
     new HtmlWebpackPlugin({
       title: "My App",
       filename: "app.html",
       //可以传入设置html的模板
       template: "./src/html/index.html"
     }) 
  ]
};
<!--./src/html/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!--会替换为配置里的title值 My App-->
    <title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
    <h1>html-webpack-plugin</h1>
</body>
</html>

clean-webpack-plugin

删除构建目录,在新一轮构建时,把之前的包都清理掉

npm install --save-dev clean-webpack-plugin
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
  plugins: [
    new CleanWebpackPlugin(),
  ]
}

webpack5可以直接在output配置clean选项

const path = require('path')
module.exports = {
  output: {
    path: path.resolve(__dirname, "./build"),
    clean:true
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容