• 所有的loader都是在node环境中执行的,所以要遵循CommonJS的规范
    • 必须导出一个函数,否则编译的时候可能会出现 must have normal or pitch function 的错误
    • loader的输入和输出都是字符串的形式 ```jsx // loaders/tpl-loader/index.js const { tplReplace } = require(‘../utils’) const { getOptions } = require(‘loader-utils’); // 获取options const { validate } = require(‘schema-utils’); // 检验options参数是否合法

    // TODO: 所有的loader都是在node环境中执行的,所以要遵循CommonJS的规范 // TODO: 必须导出一个函数,否则编译的时候可能会出现 must have normal or pitch function 的错误 // TODO: loader的输入和输出都是字符串的形式 function tplLoader(source) { source = source.replace(/\s+/g, ‘’) return export default (options) => { ${tplReplace.toString()} return tplReplace('${source}', options); } }

    module.exports = tplLoader

    // loaders/utils function tplReplace(template, templateObj) { return template.replace(/{{(.*?)}}/g, function (node, key) { return templateObj[key] }) }

    module.exports = { tplReplace };

    1. **webpack配置文件**
    2. - loader没有上传到npm,所以本地引用的时候,我们通过resolveLoader这个属性来将我们的loaders引入
    3. - 配置我们的tpl-loader,这里的loader名称和我们的文件夹名称是一致的,要不然会找不到对应的loader模块
    4. ```jsx
    5. // 我们该loader会把所有的tpl文件进行一个处理,处理之后的结果再给babel-loader做解析
    6. resolveLoader: {
    7. modules: ['node_modules', resolve(__dirname, 'loaders')], // TODO: 注意点,将本地loader引入进来
    8. },
    9. module: {
    10. rules: [{
    11. test: /\.tpl$/,
    12. use: [
    13. 'babel-loader',
    14. {
    15. loader: 'tpl-loader',
    16. options: {
    17. log: true
    18. }
    19. }
    20. ]
    21. }]
    22. },

    使用
    对于我们代码中的tpl结尾的模块都会被tpl-loader编译。

    1. // src/index.js 入口文件
    2. import hello from './hello.tpl'
    3. const app = document.querySelector('#app')
    4. const config = {
    5. name: 'hello',
    6. age: 20,
    7. }
    8. app.innerHTML = hello(config)
    9. // src/hello.tpl
    10. <div>
    11. <h1>{{name}}</h1>
    12. <h1>{{age}}</h1>
    13. </div>