web-webpack-plugin
中文文档
想全面学习 Webpack?试试它:
在线阅读全书
A good alternatives for html-webpack-plugin, can make webpack use HTML as entry and handle multi pages.
Install
npm i web-webpack-plugin --save-dev
const { WebPlugin, AutoWebPlugin } = require('web-webpack-plugin');
Feature
demo
output html filewebpack config
module.exports = {
entry: {
A: './a',
B: './b',
},
plugins: [
new WebPlugin({
// file name or full path for output file, required.
// pay attention not to duplication of name,as is will cover other file
filename: 'index.html',
// this html's requires entry,must be an array.dependent resource will inject into html use the order entry in array.
requires: ['A', 'B'],
}),
],
};
will output an file named index.html
,this file will auto load js file generated by webpack form entry A
and B
,the out html as below:
output html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script src="A.js"></script>
<script src="B.js"></script>
</body>
</html>
output directory
├── A.js
├── B.js
└── index.html
demo
use html templatewebpack config
module.exports = {
entry: {
A: './a',
B: './b',
},
plugins: [
new WebPlugin({
filename: 'index.html',
// html template file path(full path relative to webpack.config.js)
template: './template.html',
requires: ['A', 'B'],
}),
],
};
html template
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<!--load a chunk file config and output in webpack-->
<script src="B"></script>
<!--load a local reset style file direct without local var webpack-->
<link rel="stylesheet" href="./reset.min.css?_inline">
<!--load a local google analyze file direct without local var webpack-->
<script src="./google-analyze.js"></script>
</head>
<body>
<!--SCRIPT-->
<footer>web-webpack-plugin</footer>
</body>
</html>
- use
<script src="B"></script>
in html template to load required entry, theB
insrc="B"
means entry name config inwebpack.config.js
- comment
<!--SCRIPT-->
means a inject position ,except for resource load by<script src></script>
left required resource config inWebPlugin's requires option
. if there has no<!--SCRIPT-->
in html template left required script will be inject ad end ofbody
tag.
output html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<!--load a chunk file config and output in webpack-->
<script src="B.js"></script>
<!--load a local reset style file direct without local var webpack-->
<style>body {
background-color: rebeccapurple;
}</style>
<!--load a local google analyze file direct without local var webpack-->
<script src="google-analyze.js"></script>
</head>
<body>
<script src="A.js"></script>
<footer>web-webpack-plugin</footer>
</body>
</html>
demo
config resource attributeevery resource required by html,it can config some attribute as below:
_dist
only load in production environment_dev
only load in dev environment_inline
inline resource content info html,inline script and css_ie
resource only required IE browser,to achieve by[if IE]>resource<![endif]
comment
there has two way to config resource attribute:
config in html template
webpack config
module.exports = {
entry: {
'ie-polyfill': './ie-polyfill',
inline: './inline',
dev: './dev',
googleAnalytics: './google-analytics',
},
plugins: [
new WebPlugin({
filename: 'index.html',
template: './template.html',
}),
],
};
html template
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<script src="inline?_inline"></script>
<script src="ie-polyfill?_ie"></script>
</head>
<body>
<script src="dev?_dev"></script>
<!--load a local google analyze file direct without local var webpack-->
<script async src="./google-analytics.js?_dist"></script>
</body>
</html>
webpack.config.js
config in webpack config
module.exports = {
plugins: [
new WebPlugin({
filename: 'index.html',
requires: {
'ie-polyfill': {
_ie: true,
},
inline: {
_inline: true,
_dist: true,
},
dev: {
_dev: true,
},
//load a local google analyze file direct without local var webpack
'./google-analytics.js': {
_dist: true,
},
},
}),
],
};
demo
inject attr for HTML tagother attribute in config without name start with _ will be treat as attribute for HTML tag in output HTML file. e.g if a script resource with query ?crossorigin=anonymous
will lead to output HTML be <script src="B.js" crossorigin="anonymous"></script>
.
demo
auto detect html entryAutoWebPlugin
plugin can find all page entry in an directory, then auto config an WebPlugin
for every page to output an html file, you can use it as below:
webpack config
const autoPlugin = new AutoWebPlugin(
// the directory hold all pages
'./src/pages',
{
// all props below is not required
// {string,function}
// the template file path used by all pages
// if typeof template ===string: template config is html template file full path
// if typeof template ===function: template config is function(pageName)=>newFullPath ,ask user for detail
template: './src/template.html',
// { function(pageName,templateFullPath)=>htmlString }
// if provide AutoWebPlugin will use Compiler to compile org template file to html content before used it in WebPlugin
templateCompiler: (pageName, templateFullPath) => '',
// {string,function}
// get WebPlugin template's string content, high priority than template
// typeof===string: template config is html template file string content
// typeof===function: template config is function,ask user for detail
templateContent: `<!DOCTYPE html>....`,
// {string,function}
// javascript main file for current page,if it is null will use index.js in current page directory as main file
// typeof entry===string: entry config is entry file full path
// typeof entry===function: entry config is function(pageName)=>newFullPath ,ask user for detail
entry: null,
// {function}
// get WebPlugin output filename,default filename is pageName
// set filename as function(pageName)=>filename to add custom logic
filename: null,
// {Array} pre append to all page's entry
preEntrys: ['./path/to/file1.js'],
// {Array} post append to all page's entry
postEntrys: ['./path/to/file2.js'],
// {string} publicPath for css file,for js file will use webpack.publicPath
stylePublicPath: null,
// page name list will not ignore by AutoWebPlugin(Not output html file for this page name)
ignorePages: ['pageName'],
// whether output a pagemap.json file which contain all pages has been resolved with AutoWebPlugin in this way:
// {"page name": "page url",}
outputPagemap: true,
}
);
module.exports = {
// AutoWebPlugin will generate a entry for every page find in the directory hold all pages
// autoPlugin.entry({}) used to pass entrys find by AutoWebPlugin to webpack config
entry: autoPlugin.entry({
youAdditionalEntryName: 'you additional entry path',
}),
};
src directory
── src
│ ├── home
│ │ └── index.js
│ ├── ie_polyfill.js
│ ├── login
│ │ └── index.js
│ ├── polyfill.js
│ ├── signup
│ │ └── index.js
│ └── template.html
output directory
├── dist
│ ├── common.js
│ ├── home.html
│ ├── home.js
│ ├── ie_polyfill.js
│ ├── login.html
│ ├── login.js
│ ├── polyfill.js
│ ├── signup.html
│ └── signup.js
AutoWebPlugin
find all page home login signup
directory in ./src/
,for this three page home login signup
:
- will use
index.js
as main file add three chunkhome login signup
- output three html file
home.html login.html signup.html
- auto inject resource required by ever page. e.g(inject home chunk to home.html)
AutoWebPlugin find all page home login signup
in dir ./src/
then:
- use index.js as entry for every page to make a chunk named
chunk home login signup
- output html files for every page
home.html login.html signup.html
- auto inject resource required by every page(e.g home.html will inject home chunk)
ignorePages attribute
ignorePages
page name list will not ignore by AutoWebPlugin(Not output html file for this page name),type is array of string.
template attribute
template
if template is a string , i will regard it as file path for html template(full path relative to webpack.config.js)
In the complex case,You can set the template to a function, as follows using the current page directory index.html file as the current page template file
webpack config
new AutoWebPlugin('./src/', {
// Template files used by all pages
template: (pageName) => {
return path.resolve('./src', pageName, 'index.html');
},
});
entry attribute
The entry property is similar to template, and also supports callback functions for complex situations. But if the entry is empty to use the current page directory index.jsx?
As the entrance
demo
config publicPathdemo
load cssThe resource for each entry may contain css code. If you want to extract the css code to load alone rather than sneaking into the js where you need to load extract-text-webpack-plugin Separated css code, the rest of the things to me, I will automatically deal with the same as the above js css
webpack config
// webpack.config.js
module.exports = {
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: 'style-loader',
loader: 'css-loader',
}),
},
],
},
entry: {
1: './1',
2: './2',
3: './3',
4: './4',
},
plugins: [
new ExtractTextPlugin('[name].css'),
new WebPlugin({
filename: 'index.html',
template: './template.html',
requires: ['1', '2', '3', '4'],
}),
],
};
html template
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="1">
<link rel="stylesheet" href="2?_inline">
<link rel="stylesheet" href="3?_ie">
<script src="1"></script>
<!--STYLE-->
</head>
<body>
<script src="2"></script>
<!--SCRIPT-->
<footer>footer</footer>
</body>
</html>
output html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="1.css">
<style>
/**2.css**/
body {
background-color: rebeccapurple;
}</style>
<!--[if IE]>
<link rel="stylesheet" href="3.css">
<![endif]-->
<script src="1.js"></script>
<link rel="stylesheet" href="4.css">
</head>
<body>
<script src="2.js"></script>
<script src="3.js"></script>
<script src="4.js"></script>
<footer>footer</footer>
</body>
</html>
output directory
├── 1.css
├── 1.js
├── 2.css
├── 2.js
├── 3.css
├── 3.js
├── 4.css
├── 4.js
└── index.html
demo
minify output htmlWebPlugin
and AutoWebPlugin
support htmlMinify
options to minify output html use the following rules:
-
if
htmlMinify
is set - ifhtmlMinify
istrue
, builtin html minify function will used to minify output html(minify HTML only,not CSS or JS) - ifhtmlMinify
isfalse
, builtin html pretty function will used to output human read friendly html - ifhtmlMinify
is afunction
,use this functionfunction(orgHTMLString)=>minifyHTMLString
to minify html -
if
htmlMinify
is missing(undefined
) - if environment isproduction
, builtin html minify function will used to minify output html(minify HTML only,not CSS or JS)- if environment is not
production
, builtin html pretty function will used to output human read friendly html
- if environment is not
Distinguish the environment
This plugin takes into account both development environment and production environment. And only if process.env.NODE_ENV = production
current environment is production environment, others are considered to be development environment.
webpack -p
will use DefinePlugin define NODE_ENV=production
。
In practice
- redemo elegant react demo component
- stickylist react sticky header listview component
- resume my resume
- remd fast react markdown component
- use template compiler to pre-translate template
- webpack 原理与实战
- webpack2 终极优化
- 使用模版引擎预处理模版
- 使用 HTML 模版配置资源注入到 HTML
- 给 HTML 标签注入属性
- 在 webpack 里直接通过 JS 配置资源注入到 HTML
- 管理多个单页应用
- 从 JS 中提取出 CSS
- 直接注入本地文件
- 设置 PublicPath
- 编辑 HTML 模版时,监听模式下会自动编译和刷新