static-site-generator-webpack-plugin v 3.4.2

由webpack提供的小体积、精简的静态站点生成器。

将服务器渲染的世界带到你的静态构建过程中。通过执行您自己定制的、webpack编译的渲染函数,不论是传入一组要渲染的路径,还是自动抓取您的站点,它将在输出目录中渲染出相匹配的 index.html 文件组。

该插件和 React 和 React Router 这样的通用库中相得益彰,因为它允许你在构建时预渲染你的路由,而无需生产环境的 Node 服务器。

安装

npm install --save-dev static-site-generator-webpack-plugin
1

使用

webpack.config.js

const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');

module.exports = {

  entry: './index.js',

  output: {
    filename: 'index.js',
    path: 'dist',
    /* 重点!
     * You must compile to UMD or CommonJS
     * 您必须编译为 UMD 或 CommonJS,这样才能够引入 Node.js 环境中。
    */
    libraryTarget: 'umd'
  },

  plugins: [
    new StaticSiteGeneratorPlugin({
      paths: [
        '/hello/',
        '/world/'
      ],
      locals: {
        // 这里的属性将合并包为“本地属性”,并传递给导出的渲染函数
        greet: 'Hello'
      }
    })
  ]

};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

index.js

同步渲染:

module.exports = function render(locals) {
  return '<html>' + locals.greet + ' from ' + locals.path + '</html>';
};
1
2
3

通过回调函数异步渲染:

module.exports = function render(locals, callback) {
  callback(null, '<html>' + locals.greet + ' from ' + locals.path + '</html>');
};
1
2
3

通过 Promise 进行异步渲染:

module.exports = function render(locals) {
  return Promise.resolve('<html>' + locals.greet + ' from ' + locals.path + '</html>');
};
1
2
3

多重渲染

如果你每次渲染都需要生成多个文件,或者你需要更改路径的话,你可以返回一个对象而不是字符串,其中的每个键都是路径,值是文件内容:

module.exports = function render() {
  return {
    '/': '<html>Home</html>',
    '/hello': '<html>Hello</html>',
    '/world': '<html>World</html>'
  };
};
1
2
3
4
5
6
7

注意,这么做仍然会配置中的path数组中的每个入口执行渲染函数。

默认本地属性

// 当前渲染的路径:
locals.path;

// 包括所有静态资源的对象:
locals.assets;

// 高级属性:webpack 的 stats 对象
locals.webpackStats;
1
2
3
4
5
6
7
8

配置中提供的其他任何局部变量也可使用。

爬虫模式

您可以配置crawl项来自动爬取沾点,而无需手动提供路径列表。这回追踪所有的相对链接和iframe,并对其执行渲染函数:

module.exports = {
  // ...
  plugins: [
    new StaticSiteGeneratorPlugin({
      crawl: true
    })
  ]
};
1
2
3
4
5
6
7
8

注意,这可以与paths一起使用,以允许多个爬虫入口点:

module.exports = {
  // ...
  plugins: [
    new StaticSiteGeneratorPlugin({
      crawl: true,
      paths: [
        '/',
        '/uncrawlable-page/'
      ]
    })
  ]
};
1
2
3
4
5
6
7
8
9
10
11
12

自定义文件名称

通过提供以.html为结尾的路径,您可以生成自定义文件名而非默认的index.html。请注意,这可能会破坏你的路由的兼容性。

module.exports = {
  // ...
  plugins: [
    new StaticSiteGeneratorPlugin({
      paths: [
        '/index.html',
        '/news.html',
        '/about.html'
      ]
    })
  ]
};
1
2
3
4
5
6
7
8
9
10
11
12

全局变量

如果需要,可以在执行渲染函数时提供一个将存在于全局作用域中的对象。如果您正在使用的某些库或工具需要假设浏览器环境,那么这就特别有用。

例如,当使用Webpackrequire.ensure时,假设Window存在:

module.exports = {
  // ...,
  plugins: [
    new StaticSiteGeneratorPlugin({
      globals: {
        window: {}
      }
    })
  ]
}
1
2
3
4
5
6
7
8
9
10

静态资源支持

template.ejs

<% css.forEach(function(file){ %>
<link href="<%- file %>" rel="stylesheet">
<% }); %>

<% js.forEach(function(file){ %>
<script src="<%- file %>" async></script>
<% }); %>
1
2
3
4
5
6
7

index.js

if (typeof global.document !== 'undefined') {
  const rootEl = global.document.getElementById('outlay');
  React.render(
    <App />,
    rootEl,
  );
}

export default (data) => {
  const assets = Object.keys(data.webpackStats.compilation.assets);
  const css = assets.filter(value => value.match(/\.css$/));
  const js = assets.filter(value => value.match(/\.js$/));
  return template({ css, js, ...data});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

指定入口

本插件默认找到的第一个 chunk。虽然这应该在大多数情况下能够工作,如果需要的话,您也可以指定入口名称:

module.exports = {
  // ...,
  plugins: [
    new StaticSiteGeneratorPlugin({
      entry: 'main'
    })
  ]
}
1
2
3
4
5
6
7
8

压缩支持

生成的文件可以用compression-webpack-plugin进行压缩,但是首先要确保本插件在插件配置中compression-webpack-plugin的位置之前:

const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    new StaticSiteGeneratorPlugin(...),
    new CompressionPlugin(...)
  ]
};
1
2
3
4
5
6
7
8
9
10