Webpack-从入门到放弃 - 插件

Webpack 插件

Webpack 官方插件列表:https://github.com/webpack/docs/wiki/list-of-plugins

获取Webpack资源:awesome-webpack

webpack进阶之插件篇

深入了解Webpack Plugins

Hot Module Replacement Plugin

模块热加载插件。Hot Module Replacement Plugin通常会搭配Webpack dev server一起使用。它提供类似于Live Reload的功能,一旦你的代码有做更动,此插件会直接更新画面并做出相对应的变化。

通常会使用到Hot Module Replacement Plugin 的时机是当webpack dev server 不是透过 inline mode 做启动时。

inline mode:$ webpack-dev-server --devtool eval --progress --colors --hot --content-base build中的--hot会自动将Hot Module Replacement Plugin的功能加入

在配置文件中配置 devServer 属性,且其 hot属性为true时,需要加入此插件。

new webpack.HotModuleReplacementPlugin() //热加载
devServer: {
contentBase: './',
host: 'localhost',
port: 9090, //默认8080
inline: true, //可以监控js变化
hot: true, //热启动
}

HtmlWebpackPlugin

动态生成HTML文件,并支持Extract Text Plugin 自动將打包完后的 js 与css 加入。

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

要输出多个HTML页面,必须声明多次:每个页面一次

//webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports={
entry:'./index.js',
output:{
path:__dirname+'/dist',
filename:'bundle.js'
}
plugins:[
new HtmlWebpackPlugin(), //在dist目录下生成默认的index.html
//基于模板 header.html生成admin.html
new HtmlWebpackPlugin({
title: 'My App',
filename: 'admin.html',
template:'header.html',
inject: 'body',
favicon:'./images/favico.ico',
minify:true,
hash:true,
cache:false,
showErrors:false,
"chunks": {
"head": {
"entry": "assets/head_bundle.js",
"css": [ "main.css" ]
},
xhtml:false
})
]
}

配置说明:

webpack入门(六)——html-webpack-plugin

html-webpack-plugin详解

  • title: 用于生成的HTML文件的标题。模板中使用 <title><%= htmlWebpackPlugin.options.title %></title>表示
  • filename: 用于生成的HTML文件的名称,默认是index.html。你可以在这里指定子目录(例如:assets/admin.html
  • template: 模板的路径。支持加载器,例如html!./index.html
  • inject: true | ‘head’ | ‘body’ | false。把所有产出文件注入到给定的 template 或templateContent。当传入 true或者 ‘body’时所有javascript资源将被放置在body元素的底部,“head”则会放在head元素内。
  • favicon: 给html添加一个favicon './images/favico.ico' ,
  • minify:是否压缩{...} | false (最新api变动,原来是ture|false )
  • hash: true | false 。如果是true,会给所有包含的script和css添加一个唯一的webpack编译hash值。这对于缓存清除非常有用。
  • cache: true | false 。如果传入true(默认),只有在文件变化时才 发送(emit)文件。
  • showErrors: true | false。如果传入true(默认),错误信息将写入html页面。
  • chunks : 允许插入到模板中的一些chunk(例如:只有单元测试块 )。不配置此项默认会将entry中所有的chunk注入到模板中。在配置多页面时,每个页面注入的chunk应该是不相同的,需要通过该配置为不同页面注入不同的chunk;
  • excludeChunks : 允许你跳过一些chunks(例如,不要单元测试的 chunk).
  • chunksSortMode : 在chunk被插入到html之前,你可以控制它们的排序。允许的值‘none’ | ‘auto’ | ‘dependency’ | {function} 默认为‘auto’.
  • xhtml: true | false。如果是true,把link标签渲染为自闭合标签,XHTML要这么干的。默认false。

多页面

如果有许多的页面需要生成,可以参考下列方式插入配置:

var htmlFilenames=["page1","page2","page3","page4","page5","page6","page7","page8"];
for(file_name in htmlFilenames){
config.plugins.push(new HtmlWebpackPlugin({
filename: file_name +'.html',
template: 'src/assets/'+file_name +'.html'
}))
}

ProvidePlugin

webpack多页应用架构系列(四):老式jQuery插件还不能丢,怎么兼容?

全局挂载插件。 当webpack加载到的某个js模块里,出现了未定义且名称符合(字符串完全匹配)配置中key的变量时,会自动 require 配置中 value 所指定的 js 模块。

解决JQuery插件在Webpack打包后出现Uncaught ReferenceError: jQuery is not defined 的问题。

同时,模块中使用JQuery使不用再 require('jQuery');

配置方式

var providePlugin = new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
});

UglifyJsPlugin

压缩、混淆js代码

new webpack.optimize.UglifyJsPlugin()
//添加额外配置
new Webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})

No Errors Plugin

在代码出错时,不会将有错误的代码打包以确保打包完后的程序语法上的正确性。比较容易会碰到的问题是,当有使用eslint-loader来为ES6做语法检查时,不管是warning或是error都会使No Error Plugin停止打包。

ESLint 安装配置:

Eslint 配置记录(with webpack).md)

webpack多页应用架构系列(九):总有刁民想害朕!ESLint为你阻击垃圾代码

ExtractTextPlugin

从bundle中提取出特定的text到独立的文件中。可以实现把 css 从打包的 js 中抽离出来,成为独立的 css 文件。

安装(不同的Webpack版本不一样)

# https://github.com/webpack-contrib/extract-text-webpack-plugin
# for webpack 1
npm install --save-dev extract-text-webpack-plugin
# for webpack 2
npm install --save-dev extract-text-webpack-plugin@beta

配置(针对Webpack 2)

var ExtractTextPlugin = require("extract-text-webpack-plugin");
new ExtractTextPlugin(options: filename | object)
NameTypeDescription
id{String}此插件实例的唯一标识符。(仅限高级用法,默认情况下自动生成)
filename{String}结果文件的名称。可能包含[name],[id]和[contenthash]
options.allChunks{Boolean}从所有附加块(chunk)中抽取(默认情况下,它只从初始块中提取)
options.disable{Boolean}是否禁用插件
options.ignoreOrder{Boolean}禁用次序检查 (useful for CSS Modules!), 默认false
  • [name] name of the chunk
  • [id] number of the chunk
  • [contenthash] 提取的文件的内容的hash

⚠️ ExtractTextPlugin 会为每个 entry 生成一个文件, 所以当使用多entry 时,应该使用 [name], [id][contenthash] .

extract

ExtractTextPlugin.extract(options : loader | object)

从现有加载器创建提取加载程序。支持的加载器{ loader: [name]-loader -> {String}, options: {} -> {Object} }

名称类型描述
options.use{String}/ {Array}/{Object}应该用于将资源转换为CSS导出模块的Loader(s)(必需)
options.fallback{String}/ {Array}/{Object}当CSS未被提取时使用的loader(如'style-loader')(即当allChunks: false时在附加块中)
options.publicPath{String}为此loader 覆盖publicPath的设置

例:

//rules
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
//resolve-url-loader may be chained before sass-loader if necessary
use: ['css-loader', 'sass-loader']
})
}
//plugins
plugins: [
new ExtractTextPlugin('style.css')
//if you want to pass in options, you can do so:
//new ExtractTextPlugin({
// filename: 'style.css'
//})
]

CommonsChunkPlugin

webpack多页应用架构系列(三):怎么打包公共代码才能避免重复?

用webpack的CommonsChunkPlugin提取公共代码的3种方式

智能判断并打包公共代码

CommonsChunkPlugin的效果是:在你的多个页面(入口)所引用的代码中,找出其中满足条件(被多少个页面引用过)的代码段,判定为公共代码并打包成一个独立的js文件。至此,你只需要在每个页面都加载这个公共代码的js文件,就可以既保持代码的完整性,又不会重复下载公共代码了(多个页面间会共享此文件的缓存)。

参数

  • name,包含公共代码的chunk的名称(唯一标识,不用加后缀)。
  • filename,如何命名打包后生产的js文件,也可以用[name][hash][chunkhash]这些,同output.filename
  • minChunks,公共代码的判断标准:某个js模块被多少个chunk加载了才算是公共代码。
  • chunks,表示需要在哪些chunk(也可以理解为webpack配置中entry的每一项)里寻找公共代码进行打包。不设置此参数则默认提取范围为所有的chunk。

实例

new webpack.optimize.CommonsChunkPlugin({
name: 'commons',// 公共代码的chunk名为'commons'
filename: 'commons/[name].bundle.js', // 生成后的文件名
minChunks: 4, // 设定要有4个chunk(即4个页面)加载的js模块才会被纳入公共代码。
});

CommonsChunkPlugin 也可以使用多次,这样可以多不同的页面抽取不同的commons

multiple-commons-chunks

抽取公共代码,并分离第三方库(如Vue)

https://fakefish.github.io/react-webpack-cookbook/Split-app-and-vendors.html

DllPlugin

https://github.com/webpack/docs/wiki/list-of-plugins

webpack多页应用架构系列(十一):预打包Dll,实现webpack音速编译

输出 “dll” 包. Dll 不会执行你的模块中的任何代码,他们只是包含这些模块. 一个 dll 包会导出一个函数,这个函数可以通过 id 被用于 “require” 模块 (内部require函数). 除此之外,一个manifest json 文件被写入到包含从真实请求到模块id的映射的指定位置。

结合此插件与output.library 配置,可暴露一个 dll 函数,即进去全局范围。

new DllPlugin({
path: path.join(__dirname, "manifest.json"),
name: "[name]_[hash]",
context: __dirname
})
  • path: 指向manifest json 文件的绝对路径 (输出)
  • name: 暴露的dll函数的名称(与output.library保持一致)
  • context (可选):清单文件中的请求的上下文,默认为webpack上下文
output: {
path: path.join(__dirname, "js"),
filename: "MyDll.[name].js",
library: "[name]_[hash]"
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, "js", "[name]-manifest.json"),
name: "[name]_[hash]" //与`output.library`保持一致
})
]

DllReferencePlugin

引用一个预期可用的dll函数。清单文件可以用于将名称映射到可通过此dll函数访问的模块标识。

可以用来使用由DllPlugin 创建的 dll bundle + manifest 。

可用于两种不同的模式:

  • Scoped mode

    dll的内容可以在模块前缀下访问。即有scope = "xyz"时,可以通过require("xyz/abc")访问dll中的一个文件abc

  • Mapped mode

    dll的内容被映射到当前目录。如果所需的文件与dll中的文件匹配(解析后),则使用dll中的文件。注意:因为这发生在解析后,每个在dll中的文件必须也被在同一路径的dll用户使用。即如果dll包含jquery和文件abcrequire("jquery")require("./abc") 将使用dll中的文件。

new DllReferencePlugin({
context: __dirname,
scope: "xyz",
manifest: require("./manifest.json"),
name: "./my-dll.js",
sourceType: "commonsjs2",
content: { ... }
})
  • context: (absolute path) 清单中请求的上下文(或内容属性)
  • scope (optional): 用于访问dll中内容的前缀
  • manifest (object): 包含 contentname的对象
  • name (optional): dll所暴露的名称(默认为manifest.name)(另见externals
  • sourceType (optional): dll如何暴露的类型(默认为"var")(另见externals
  • content (optional): 从请求到模块id的映射(默认为manifest.content

通过 <script>标签使用dll

Dll 包: output.library = "[name]_[hash]" output.libraryTarget = "var"``DllPlugin.name = "[name]_[hash]"
Dll 使用者: DllReferencePlugin.sourceType = "var"

通过node.js使用dll

Dll 包: output.libraryTarget = "commonjs2"

Dll 使用者: DllReferencePlugin.sourceType = "commonjs2" DllReferencePlugin.name = "./path/to/dll.js"

copy-webpack-plugin

http://stackoverflow.com/questions/27639005/how-to-copy-static-files-to-build-directory-with-webpack

https://github.com/kevlened/copy-webpack-plugin

copy static files directly from static to build :

var CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
context: path.join(__dirname, 'your-app'),
plugins: [
new CopyWebpackPlugin([
{ from: 'static' }
])
]
};

或者使用file-loader

html 文件:

webpack.config.js :

module.exports = {
...
module: {
loaders: [
{ test: /\.(html)$/,
loader: "file?name=[path][name].[ext]&context=./app/static"
}
]
}
};

在 js 文件中:

require.context("./static/", true, /^\.\/.*\.html/);

./static/是相对于你的js文件的路径

context 的设置:http://www.qinshenxue.com/article/20170315092242.html

实例:开发时引入本地 static文件夹中的css文件

vue-cli-webpack 项目

配置

webpack.dev.conf.js配置文件中,配置CopyWebpackPlugin(项目的webpack.prod.conf.js中已经配置了此插件)

var path = require('path')
var CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = merge(baseWebpackConfig, {
context: path.resolve('./'), // 项目根目录、这样配置context就不需要修改 entry 中的app地址了
// ... 其他配置
plugins: [
// ... 其他插件
new CopyWebpackPlugin([{
from: path.resolve('./static'),
ignore: ['.*']
}])
]
})

使用css

index.html文件中的head部分

<!--
本地测试时:需要配合copy-webpack-plugin插件
生产环境可以使用CDN
-->
<link rel="stylesheet" href="./static/css/font-awesome.min.css">
<link rel="stylesheet" href="./static/css/iview.css">
<link rel="stylesheet" href="./static/css/ol.css">

externals

http://www.tangshuang.net/3343.html

exports.externals = {
jquery: 'jQuery', // require('jquery')
openlayers: 'ol'
}

externals: {jquery: 'jQuery'}这个里面的jquery是指require('jquery')中的jquery,而jQuery就是上面代码中的红色字。简单翻译一下,就是说“当require的参数是jquery的时候,使用jQuery这个全局变量引用它”,你可以在这里详细阅读这句话:jQuery in the externals indicates that your bundle will need jQuery variable in the global form.。

文章目录
  1. 1. Webpack 插件
    1. 1.1. Hot Module Replacement Plugin
    2. 1.2. HtmlWebpackPlugin
      1. 1.2.1. 配置说明:
      2. 1.2.2. 多页面
    3. 1.3. ProvidePlugin
      1. 1.3.1. 配置方式
    4. 1.4. UglifyJsPlugin
    5. 1.5. No Errors Plugin
    6. 1.6. ExtractTextPlugin
    7. 1.7. 安装(不同的Webpack版本不一样)
      1. 1.7.1. 配置(针对Webpack 2)
      2. 1.7.2. extract
    8. 1.8. CommonsChunkPlugin
      1. 1.8.1. 参数
      2. 1.8.2. 实例
      3. 1.8.3. 抽取公共代码,并分离第三方库(如Vue)
    9. 1.9. DllPlugin
    10. 1.10. DllReferencePlugin
      1. 1.10.0.1. 通过
|