3-5 使用plugins让打包更便捷

1. 简介

loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。简言之,我们利用 loader 来处理非 js 类型的模块,用 plugin 来简化我们的打包工作。

2. htmlWebpackPlugin

前面,我们将 index.html 放在 src 和 build 目录之外,就是因为考虑到index.html的复用性,不用每次生成 build 文件夹,都要专门手动 copy 一份 index.html 到build。但是事实上,index.html 和index.js一样都属于源文件,应该放在src之下,而输出目录也应该包含 index.html。那么,有没有办法能自动帮我们生成index.html到build目录,帮助我们简化打包流程呢?答案是有的,就是htmlWebpackPlugin插件。
插件也是npm包,使用前需要安装。

cnpm install --save-dev html-webpack-plugin

这个插件会我们自动生成 html 文件到指定目录,并且会自动引入打包好的js脚本和 css 文件。
只需进行如下配置:

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

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'build'),
        publicPath: 'build/'
    },
    plugins: [new HtmlWebpackPlugin()],
    module: {...} // 这里忽略module详细内容,大家可以参考前面章节补全
};

然后我们开始打包,发现 build 目录下,确实多出了index.html.


image.png

并且自动引入了打包好的bundle.js。但是我们打开 index.html。发现页面什么也没有,看一下src 目录的index.html:


image.png

发现区别在于 build 目录下的 index.html 少了 id="root"的div。其实,src 下面即使没有index.html文件,打包后同样会生成上述index.html文件。也就是生成的index.html和源文件的html并无关系,这显然不是我们想要的效果。那么有没有办法让生成的 index.html 是根据 src 下的 index.html 内容来决定的呢。答案是有的。
如下,我们在src下面建立一个最简单的html文件,注意我们并不需要显示引入最后的打包js文件,这为我们创造了极大的便利:
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>esmodule-oop</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

然后在配置文件增加如下配置:

    plugins: [new HtmlWebpackPlugin({
        template: './src/index.html'
    })],

再次打包。如下:

image.png

竟然还是什么也没有。问题很明显,src引用路径报错了。原因在于3-2 使用loader打包静态资源(图片)
中,为了保证图片的引用地址正确,我们加了publicPath这一配置。当时一笔带过,现在为大家详细讲述一下这个配置的用途。

3. publicPath

为什么有了path的情况下还需要一个publicPath呢。我们先来解释一下什么是path就是输出文件的目标路径,也就是打包好的代码我们能在哪里找到。如果打包好的html文件和其他静态资源都放在一起,在生成资源引用路径时只要按照他们处在同格目录下即可。不管丢到哪里都能正常运行。但事实上,我们生成的html文件,往往和其他资源并不放在一处,另外,它们也并不都是处在同级目录,我们很可能为这些资源文件单独生成一个父目录,然后丢在其他地方。如果这些资源换了位置,那么之前的引用路径就会出错。
publicPath 就是针对这种情况,用来指明资源文件最终的引用地址。它并不影响我们打包文件的输出地址,只是会影响打包后生成文件内的引用路径。如果我们更换了发布时的静态资源服务器地址,只需在打包前修改publicPath即可。
这里,由于html和其他静态资源在一起,我们可以不配置publickPath,也可以如下配置:

    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'build'),
        publicPath: '/webpack-study/build/'
    }

这里之所以这么配置,是因为webstorm点开html时,根目录对应整个项目文件的父目录。
当然,更复杂的情况是,我的js文件,css文件,图片文件,并不想放在一起。这种情况是很常见的,就比如我们的图片经常放在cdn。这时,我们就需要区分不同的资源文件,配置不同的publicPath了,如下:

entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'build')
    },
    plugins: [new HtmlWebpackPlugin({
        template: './src/index.html'
    })],
    module: {
        rules: [
            {
                test: /\.(jpg|jpeg|png|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name].[ext]',
                        limit: 2048,
                        publicPath: '/images/'
                    }
                }
            },
            ...
        ]
    }
};
image.png
image.png

js资源和图片资源的引用目录就不一样了。

4. clean-webpack-plugin

这里,再为大家介绍一个简单常用的插件。试想这种情况,我们修改了输出文件的名称,重新打包:


image.png

可以看到生成了新的dist.js,但是老的bundle.js也还存在。如果存在多个文件的变动,导致旧的生成文件不需要时,webpack并不能为我们智能的删除。这就会造成无用文件遗留,打包文件增大。最好是,每次生成新的打包文件时,能够先清理一下打包目录。这个时候就可以借助clean-webpack-plugin。
先安装:

cnpm i clean-webpack-plugin -D

用法和html-webpack-plugin类似。

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'dist.js',
        path: path.resolve(__dirname, 'build')
    },
    plugins: [new HtmlWebpackPlugin({
        template: './src/index.html'
    }), new CleanWebpackPlugin(['build'])],
...

打包,发现报错了。

image.png

翻开https://www.npmjs.com/package/clean-webpack-plugin,我们发现原来clean-webpack-plugin插件导出和导入方法已发生变化,改成如下即可:

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

打包后bundle.js不见了。


image.png

5 plugins

可以看到,其实plugins就是允许我们在打包的不同阶段,插入一些指定的操作。

参考

https://www.webpackjs.com/concepts/#%E6%8F%92%E4%BB%B6-plugins-
https://www.webpackjs.com/api/plugins/
https://www.webpackjs.com/plugins/
https://www.webpackjs.com/plugins/html-webpack-plugin/
https://www.webpackjs.com/configuration/
https://www.webpackjs.com/guides/output-management/

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

推荐阅读更多精彩内容