webpack学习之3.html-webpack-plugin自动创建html

介绍

插件html-webpack-plugin实现打包时生成html文件,自动引入打包的资源并可以插入hash。
还可以指定模板,默认lodash模板。

创建初始项目

在这里插入图片描述

// package.json
{
  // ...
  "scripts": {
    "build": "webpack --progress",
    "server": "node server.js"
  },
  "devDependencies": {
    "css-loader": "^3.5.3",
    "express": "^4.17.1",
    "html-webpack-plugin": "^4.3.0",
    "mini-css-extract-plugin": "^0.9.0",
    "style-loader": "^1.2.0",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-middleware": "^3.7.2",
    "webpack-hot-middleware": "^2.25.0"
  }
}
// webpack.config.js
const path = require('path');
// 加载插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const hotMiddlewareScript = 'webpack-hot-middleware/client?quiet=true';
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 加载html-webpack-plugin

module.exports = {
    devtool: 'cheap-module-eval-source-map',
    entry: {
        main: [hotMiddlewareScript, './src/index.js'],
        util: [hotMiddlewareScript, './src/util.js']
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.css$/, // 根据正则匹配.css结尾的文件
                use: [ // 配置loader,倒序使用
                    {
                    	loader: MiniCssExtractPlugin.loader,
                        options: {
                            hmr: true // process.env.NODE_ENV === 'development'
                        }
                    },
                    { loader: 'css-loader' }
                ]
            }
        ]
    },
    plugins: [
        // 用 MiniCssExtractPlugin 抽离出 css 文件
        new MiniCssExtractPlugin({
            filename: '[name].css'
        }),
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin() // 使用html-webpack-plugin
    ],
}
// server.js
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware')

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

// 告诉express使用webpack-dev-middleware并使用webpack.config.js
app.use(webpackDevMiddleware(compiler));

app.use(webpackHotMiddleware(compiler));

app.use(express.static('dist'))


// 在8080端口运行文件
app.listen(8080, function () {
  console.log('Example app listening on port 8080!\n');
});
// src/index.js
import './css/style.css';
console.log('this is index.js')

// src/util.js
let app = document.getElementById('app');
if (!app) {
    app = document.createElement('div');
    app.id = 'app';
    document.body.appendChild(app);
    app.innerText = 'I from createElement'; // 标记app为util创建的
} else {
    app.innerText = 'I from HTML element'; // 标记app是html页面已有的
}
// src/css/style.css
body{
    font-size:14px;
    line-height: 1.8em;
    color: #333;
}

打包,npm run build,查看dist
在这里插入图片描述
自动生成了一个html文件,将入口文件main.js util.js按entry配置的顺序引入到body的底部
将css文件引入到了head的底部

// 格式化后
<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Webpack App</title>
		<meta name="viewport" content="width=device-width,initial-scale=1">
		<link href="main.css" rel="stylesheet">
	</head>
	<body>
		<script src="main.js"></script>
		<script src="util.js"></script>
	</body>
</html>

HtmlWebpackPlugin 配置

参数类型默认值描述
titleStringWebpack App用于生成HTML文档的标题
filenameString‘index.html’将HTML写入的文件。默认是index.html。你也可以在此处指定子目录(比如:assets/admin.html)
templateString‘’根据自己的指定的模板文件(相对路径或绝对路径)来生成特定的 html 文件。
模板类型可以是 html, jade, ejs, hbs 等等,默认情况下,它将使用src/index.ejs(如果存在)。
html模板可以使用lodash语法,其他模板需要安装对应的loader。
templateContentString|Function|falsefalse可代替模板使用以提供内联模板
templateParametersBoolean|Object|Functionfalse允许设置或覆盖模板中使用的参数
injectBoolean|Stringtrue资源注入选项,将所有打包的资源注入到template或templateContent,枚举值:true | ‘body’ | ‘head’ | false。
true | ‘body’ 将js放置到body底部。
‘head’ 将js放置在head元素底部。
false 不注入任何资源(css、js以及viewport meta)
scriptLoading‘blocking’|‘defer’‘blocking’配置script标签的defer属性。类似于将script放入文档最底部
faviconString‘’favicon 文件所在的路径名
metaObject{}允许注入meta标签,例如:{viewport: ‘width=device-width, initial-scale=1’}
baseObject|String|falsefalse插入一个base标签
minifyBoolean|Objectwebpack mode='production’时默认为true,否则默认为false设置是否压缩html,及如何压缩。
它使用 html-minifier-terser 压缩,当为true时使用默认配置见文档
hashBooleanfalse设置为true时会在script引用的js文件(output.filename)后附加webpack的hash值,例如:
cacheBooleantrue只有内容被改变时才生成文件(没明白什么意思)
showErrorsBooleantrue是否显示错误提示,会在html页面中将错误信息写在一个pre标签中。
chunks??单独设置要注入的资源,用于多入口打包。
chunksSortModeString|Functionauto用于设置将chunks注入时的排序。可设置为:‘none’ | ‘auto’ | ‘manual’ | {Function}
excludeChunksArray.‘’用于排除哪些资源,例如:单元测试

使用模板

// webpack.config.js
// ...
	new HtmlWebpackPlugin({
	    inject: false, // 禁用自动注入
        templateContent: ({htmlWebpackPlugin}) => `
	        <!doctype html>
            <html>
                <head>
                ${htmlWebpackPlugin.tags.headTags}
                </head>
                <body>
                ${htmlWebpackPlugin.tags.bodyTags}
                </body>
            </html>
        `
	})
// ...

打包生成html文件:

<!doctype html>
<html>
	<head>
		<link href="main.css" rel="stylesheet">
	</head>
	<body>
		<script src="main.js"></script>
		<script src="util.js"></script>
	</body>
</html>

基本一致,区别是没有插入默认的title meta。配置title meta 并 增加一个自定义参数,看看如何使用:

// webpack.config.js
// ...
    new HtmlWebpackPlugin({
        inject: false, // 禁用自动注入
        title: 'my App',
	    meta: {
	    	viewport: 'width=device-width, initial-scale=1'
	    },
        templateParameters: {
            h1text: 'hello World'
        },
        templateContent: ({htmlWebpackPlugin,h1text}) => `
            <html>
                <head>
                ${htmlWebpackPlugin.tags.headTags}
                </head>
                <body>
                <h1>${h1text}</h1>
                ${htmlWebpackPlugin.tags.bodyTags}
                </body>
            </html>
        `
    })
// ...

打包生成html文件:

<!doctype html>
<html>
	<head>
		<title>my App</title>
		<meta name="viewport" content="width=device-width,initial-scale=1">
		<link href="main.css" rel="stylesheet">
	</head>
	<body>
		<h1>hello World</h1>
		<script src="main.js"></script>
		<script src="util.js"></script>
	</body>
</html>

模板可使用的信息

上面示例看到,html-webpack-plugin将一些对象和自定义参数传入到模板中使用。

参数名描述
htmlWebpackPlugin插件可用数据
htmlWebpackPlugin.options插件的配置信息
htmlWebpackPlugin.tags插件要注入的tag信息,包括<base><meta><script><link>,可以直接在模板中使用。
htmlWebpackPlugin.tags.headTags 要注入head的标签;
htmlWebpackPlugin.tags.bodyTags 要注入body的标签。
htmlWebpackPlugin.files直接访问编译期间使用的文件。
webpackConfigwebpack的配置信息,例如:webpackConfig.output.publicPath
compilationthe webpack compilation object
templateParameters中自定义参数可直接用参数名访问

使用模板文件

创建src/index.html,并指定为模板,使用lodash语法,内容如下:

<!doctype html>
<html>
	<head>
		<title><%= htmlWebpackPlugin.options.title %></title>
		<%= htmlWebpackPlugin.tags.headTags %>
	</head>
	<body>
		<h1><%= h1text %></h1>
		<div id="app"></div>
		<%= htmlWebpackPlugin.tags.bodyTags %>
	</body>
</html>
// webpack.config.js
// ...
    new HtmlWebpackPlugin({
        template: './src/index.html',
        inject: false, // 禁用自动注入
        title: 'my App',
        meta: {
            viewport: 'width=device-width, initial-scale=1'
        },
        templateParameters: {
            h1text: 'hello World'
        }
    })
// ...

打包生成html文件,与templateContent方式一样,这里新增了id为app的div,可以发现,自定义的内容也会保留。

生成多个html文件

生成多个html文件,需要在插件plugins数组中多次声明该插件:

// webpack.config.js
// ...
    plugins: [
        // ...
        new HtmlWebpackPlugin({
            template: './src/index.html',
            inject: false, // 禁用自动注入
            title: 'my App',
            meta: {
                viewport: 'width=device-width, initial-scale=1'
            },
            templateParameters: {
                h1text: 'hello World'
            }
        }),
        new HtmlWebpackPlugin({
            filename: 'test.html',
            title: 'Test',
            chunks: ['util'],
        })
    ],
// ...

打包后,生成了index.html和test.html

clean-webpack-plugin

现在dist中的文件都是打包生成的了,为避免每次打包会遗留文件,可用clean-webpack-plugin插件在每次打包前,清空dist目录。

默认情况下,此插件将在每次成功构建后删除webpack的output.path目录中的所有文件,以及所有未使用的webpack资源。

安装配置

npm install -D clean-webpack-plugin
// webpack.config.js
// ...
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
	//...
    plugins: [
    	// ...
	    // 取消生成第二个html文件
        // new HtmlWebpackPlugin({
        //     filename: 'test.html',
        //     title: 'Test',
        //     chunks: ['util'],
        // }),
        new CleanWebpackPlugin()
	]	
};

打包后,dist/test.html被删除

HMR

使用html-webpack-plugin生成的index.html文件会实时编译,但不会自动刷新页面。
可通过loader或其他方式实现。

参考

html-webpack-plugin npm

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值