起因:因为一直用ejs当作模板,就使用 ejs-webpack-loader ,但是发现了个倒霉的问题,这个loader是用的ejs2.0,不支持es6语法。没有办法,按照官方网站自己撸一个试试。

思路

整个引用的思路还是按照ejs-webpack-loader的来的,实际上要支持EJS的 <%- include('user/show', {user: user}); %> ,看起来比较麻烦,webpack处理的过程中,不能识别include,所以只能用 require 的方法来解决。

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title><%= htmlWebpackPlugin.options.title %></title>
  7. </head>
  8. <body>
  9. <%- require('./components/header.html')({ name: 'zhangsan' }); %>
  10. <main>
  11. index
  12. </main>
  13. </body>
  14. </html>

header.html

<header class="page-header">
  Hi <%= name %>
</header>

大概就是这样用。

代码

webpack.ejs.loader.js

const { getOptions } = require('loader-utils');
const ejs = require('ejs');
const merge = require('merge');
const path = require('path');

module.exports =  function (source) {
  this.cacheable && this.cacheable();

  const options = getOptions(this); // 获取loader的配置

  const opts = merge({ // 合并配置
    client: true
  }, options);

  const template = ejs.compile(source, merge(opts, {
    filename: path.relative(process.cwd(), this.resourcePath),
    webpack: this
  })).toString();

  return `module.exports =  ${template}`;
}

webpack.config.js 加入loader

rules: [{ 
  test: /\.(ejs|html)$/i, 
    use: [
      { 
        loader: path.resolve(__dirname, 'webpack.ejs.loader.js'),
        options: {
          a: '111'
        }
      } 
    ] 
}]

好像可以了,太简单了!!

后面发现了一个 ejs-compiled-loader,直接把compile移过来了。

总结

看起来loader就是一个function,内容(source)直接传递过来,处理后 return 出去就行了。webpack 本身提供的内容,通过文档查一下就可以了。

参考文档:https://webpack.js.org/contribute/writing-a-loader/