介绍
有时候部分页面内容是通过富文本实现,维护这个富文本也需要工程化的支持,方便解决兼容和开发规范性问题。
想法
利用webpack打包工具和插件,把html js css 合并成一个大html
方案
主要解决html,js,css 如何内容直接输出内联到一个页面里。
html 内联
方案1: 使用 inline-html-loader
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<link href="./content.html?__inline">
</body>
</html>
方案2: 使用 raw-loader
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
${ require('!raw-loader!./content.html')}
</body>
</html>
js 内联
使用 raw-loader
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
${ require('!raw-loader!./content.js')}
</body>
</html>
css 内联
方案1
使用 html-inline-css-webpack-plugin
缺点:生成的css 一般只能指定到具体,依赖 mini-css-extract-plugin
const HTMLInlineCSSWebpackPlugin = require('html-inline-css-webpack-plugin').default;
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HTMLInlineCSSWebpackPlugin = require("html-inline-css-webpack-plugin").default;
module.exports = {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css'
}),
new HtmlWebpackPlugin(),
new HTMLInlineCSSWebpackPlugin()
]
}
方案2
- 使用raw-loader在template/html页面直接动态引入 优点,足够灵活,可以把希望插入的html js,css 放在任何一个地方。
<style>
${ require('!raw-loader!postcss-loader!less-loader!./content.less')}
</style>
注意:
style-loader加载只能在js 输出<style>内容, 下面是关于整理webpack关于css的处理总结
方案确定
由于raw-loader的灵活性,统一使用raw-loader
搭建
依赖的库
"devDependencies": {
"@babel/core": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"autoprefixer": "^9.6.2",
"babel-loader": "^8.0.5",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^5.1.2",
"core-js": "^3.35.1",
"css-loader": "^2.1.1",
"file-loader": "^6.2.0",
"html-inline-css-webpack-plugin": "^1.8.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.6.0",
"postcss-loader": "^3.0.0",
"raw-loader": "^0.5.1",
"style-loader": "^0.23.1",
"url-loader": "^4.1.1",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.11.0"
},
目录结构介绍
src/content/ 实际开发代码
这里是自己开发的代码
detail.html
<div class="container">
<h2>富文本标题</h2>
<section>
<p>
我是内容
</p>
</section>
</div>
detail.js
console.log("测试。。。")
detail.less
@mycolor: gray;
body {
margin: 0;
padding: 0;
}
section p {
font-size: 30px;
color: @mycolor;
}
src/template/ 模板
核心模板文件,动态引入 html js css。
detail-all.html
<style>
${ require('!raw-loader!postcss-loader!less-loader!../content/detail.less')}
</style>
${ require('!raw-loader!../content/detail.html')}
<script>${ require('!raw-loader!babel-loader!../content/detail.js')}</script>
这里的 postcss-loader和 babel-loader 会自动读取环境配置好了 .babelrc 和 postcss.config.js
index.html 调试的模板页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板内容</title>
<style>
.full-box {
border: 1px solid red;
}
</style>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>
<h1>
模板内容
</h1>
<div class="full-box" >
</div>
<script type="text/javascript">
$(".full-box").load("detail-all.html");
</script>
</body>
</html>
index.js
webpack打包需要的index.js 入口文件,只是为了让webpack能够正常启动,无任何其他功能。
插件plugins/
plugins/remove-main-js-plugin.js :用来删除多输出的 main.js <script>标签
const HtmlWebpackPlugin = require('html-webpack-plugin');
class RemoveMainJsPlugin {
apply(complier) {
//这是一个异步的钩子
complier.hooks.emit.tapAsync("HtmlWebpackPlugin", (compilation, cb) => {
let html = compilation.assets["detail-all.html"].source();
html = html.replaceAll(`<script type="text/javascript" src="main.js"></script>`,"") //这里去掉引入main.js的代码
compilation.assets["detail-all.html"] = {
source: function () {
// 定义文件的内容
return html;
},
size: function () {
// 定义文件的体积
return html.length;
},
};
cb();//记得要调用回调cb才能往下进入下一个钩子
});
}
}
module.exports = RemoveMainJsPlugin
webpack.config.js
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HTMLInlineCSSWebpackPlugin = require('html-inline-css-webpack-plugin').default;
const CopyWebpackPlugin = require("copy-webpack-plugin");
const RemoveMainJsPlugin = require("./plugins/remove-main-js-plugin");
module.exports = (env, argv) => {
let plugins = []
if (argv.mode === 'production') {
plugins = plugins.concat( new CleanWebpackPlugin(
{
protectWebpackAssets: false,
cleanAfterEveryBuildPatterns: ['main.js'], //删除main.js资源
}
))
}
plugins = plugins.concat(
new htmlWebpackPlugin({
title: "title",
filename: "detail-all.html",
template: "./src/template/detail-all.html",
minify: {
html5: false,
collapseWhitespace: false, //去空格
preserveLineBreaks: false, //去换行
minifyCSS: false,
minifyJS: false,
removeComments: false //去备注
},
templateParameters: {
},
}),
new CopyWebpackPlugin([
{ from: 'src/template/index.html'},
]),
new RemoveMainJsPlugin()
)
return {
entry: "./src/template/index.js", //暂时不使用
output: {
filename: "main.js",//利⽤占位符,⽂件名称不要重复
path: path.resolve(__dirname, "dist")//输出⽂件到磁盘的⽬录,必须是绝对路径
},
module: {
},
plugins: plugins,
devServer: {
port: 9001,
},
};
}
通过CleanWebpackPlugin 的构子方法删除main.js文件。
new CleanWebpackPlugin( { protectWebpackAssets: false, cleanAfterEveryBuildPatterns: ['main.js'], //删除main.js资源 } )
使用
"scripts": {
"dev": "webpack-dev-server --mode=development --config webpack.config.js",
"build": "webpack --mode=production"
},
1. 安装
npm install
2. 启动开发
npm run dev
访问:http://localhost:9001/ 默认端口9001
3. 构建
npm run build
构建后的detail-all.html为最终要上传到后台的富文本内容
4. 调试
只需要启动 npm run dev调试即可
访问:http://localhost:9001/
5. 发布
只需要启动 npm run build,复制detail-all.html到后台富文本即可
查看打包效果,可以右键生成的/dist/index.html 使用live server启动查看效果。
5.1构建结果
<style>
body {
margin: 0;
padding: 0;
}
section p {
font-size: 30px;
color: gray;
}
</style>
<div class="container">
<h2>富文本标题</h2>
<section>
<p>
我是内容
</p>
</section>
</div>
<script>console.log("测试。。。");
var a = 1;</script>