EJS中webpack包的版本控制

时间:2017-04-19 05:18:21

标签: javascript express caching webpack ejs

我正在使用Express和ReactJS创建应用程序。 为了拆分大组件,我使用延迟加载,在webpack中我添加chunkhash来查询在浏览器中创建版本并提供新版本。 但遗憾的是我的捆绑文件在EJS模板中提供,因为我使用Express作为后端并且它是简单的脚本标记。

<script src="/build/bundle.js" type="text/javascript" defer></script>

那么如何在EJS模板中提供版本控制呢?在这种情况下,最佳做法是什么?

希望我没有问过愚蠢的问题。

提前致谢!

1 个答案:

答案 0 :(得分:1)

完全可行。在一天结束时,脚本标签是字符串,对吗?

这是我做的, 使用assets-webpack-plugin创建一个带有webpack捆绑输出的json文件。

假设它创建了一个assets.json文件。

在设置快速服务器时,需要该文件并将其放在本地服务器中。 req.locals.assets = require('path/to/assets.json')

现在您只需要构建字符串标记并包含在模板中。 为此,您可以编写一个ejs帮助程序,它将获取您希望在模板中的js文件数组并返回脚本标记。

这样的东西
function renderJSTags(jstags) {
    let out = '';

    _.each(jstags, function (js) {
        if (typeof js === 'string') {
            out = out + renderTag({
                'name': 'script',
                'opts': objToKeyval({
                    'src': js,
                    'nonce': `${_res.locals.nonce}` // you should be using nonce along with good CSP
                })
            });
        } else {
            out = out + renderTag({
                'name': 'script',
                'opts': objToKeyval(js)
            });
        }
    });

    return out;
}

function objToKeyval(obj) {
    return _.map(obj, function (val, key) {
        return {'key': key, 'val': val};
    });
}

function renderTag(obj) {
    let tag = '<' + obj.name + ' ';

    _.each(obj.opts, function (opt) {
        if ((obj.name === 'link' || obj.name === 'script') &&
            (opt.key === 'href' || opt.key === 'src') &&
            !url.parse(opt.val, false, true).host) {
            opt.val = opt.val;
        }

        tag += opt.key + '="' + opt.val + '" ';
    });

    if (obj.selfclose) {
        tag += '/>';
        return tag;
    }

    tag += '></' + obj.name + '>';

    return tag;
}

这将我们带到最后一步 在路径处理程序中,将js标记数组传递给视图以及传递的数据。

router.get('/', (req, res, next) => {
    const assets = req.locals.assets;

    const payload = {
        // your data
        'name' : 'John Doe',
        'js': [
            assets.webpackEntryPoint1.js,
            assets.webpackEntryPoint2.js,
        ]
    }

    res.render('/path/to/template', payload);
});