为了解决前端分享截图痛点,旨在项目 webpack 打包阶段,提取出分享DOM的信息。
从 html-webpack-plugin
中提取 css
和 html
,并全局输出 _get_extract_template_
方法,获取相应的模板。
Note:插件强依赖 html-webpack-plugin
,请确保项目中已经安装
npm i --save-dev template-extract-plugin
yarn add -D template-extract-plugin
-
<!--template-extract-css-->
style
标签插入的位置 -
<!--template-extract-dom-->
动态DOM插入的位置 -
<!--template-extract-js-->
JS代码插入的位置 -
<!--template-extract-del-start-->
需要移除的代码块起始标志 -
<!--template-extract-del-end-->
需要移除的代码块结束标志
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!--template-extract-css-->
<title>test</title>
<!--template-extract-del-start-->
<style>
.loading{}
</style>
<!--template-extract-del-end-->
</head>
<body>
<div id='root'>
<!--template-extract-del-start-->
<div class='loading'></div>
<!--template-extract-del-end-->
<!--template-extract-dom-->
</div>
</body>
<!--template-extract-js-->
</html>
const TemplateExtractPlugin = require('template-extract-plugin');
// ……
new TemplateExtractPlugin({
/** 将模板注入到单独的 js 文件,而非 html 的内联 script 标签 */
injectInJs: true,
/** 自定义文件名,暂只支持 hash 后缀,默认名为 template.extract.js */
fileName: 'js/snapshot.template.[hash:8].js',
/** 是否同步加载脚本,默认 false */
sync: false,
/** 是否禁用插件执行,默认 false */
disable: false,
/** 模板内容是否保留原 html 的 script标签,默认全部移除 */
scriptTag: false,
/** 调用模板代码的注入位置,值可以是 head-top、head-bottom、body-top、body-bottom,默认 body-bottom */
position: 'head-top'
})
Note:插件强依赖 css-loader
和 html-webpack-plugin
,请优先注册 html-webpack-plugin
保证顺序,注意 TemplateExtractPlugin.loader
和 css-loader
的顺序。
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TemplateExtractPlugin = require('template-extract-plugin');
module.exports = {
// 省略若干……
module: {
rules: [
{
test: /.(css|less)$/,
use: [
'style-loader',
TemplateExtractPlugin.loader, // 置于 css-loader 前
'css-loader',
'less-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'project',
// ……
}),
// ……
new TemplateExtractPlugin({
injectInJs: true
}) // 置于 HtmlWebpackPlugin 后
]
};
// src/ShareContent.jsx
export default props => <div>分享的{props.title}内容</div>;
// src/index.jsx
import ReactDOMServer from 'react-dom/server';
import ShareContent from './ShareContent';
const App = () => (
<div>
内容若干……
<button
onClick={() => {
const content = ReactDOMServer.renderToString(ShareContent({
title: '神奇的'
}));
if (window._get_extract_template_) {
let shareDOM;
if (customStyle) {
// 自定义了 style 样式
shareDOM = window._get_extract_template_(content, customStyle);
} else {
shareDOM = window._get_extract_template_(content);
}
// 接下去的逻辑可能是:发送你的分享DOM到某个node服务,而后用无头浏览器生成图片的相关信息返回给客户端
// ajax.send(shareDOM);
}
}}
>
分享按钮
</button>
</div>
);
Note:如果你的静态资源 src
地址是自动获取 protocol 的方式(//cdn.xxx.com/image.jpg
),可能你需要手动为其添加 protocol,以便它能在无头浏览器中正常执行。