Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get webpack2 and underscore-template loader + babel to work without getting "Module build failed: SyntaxError: 'with' in strict mode (5:0)"

I have a underscore template loader in my webpack2 config that is transpiled with babel. It fails at compile time because with is used in the code compiled code. Here is the relevant part in my loaders in webpack.config.js:

I have this section under loaders:

{
    test: /\.html$/,
    use: [
        {
            loader: 'babel-loader',
            query: {
                presets: [
                    ['es2015', { modules: false }],
                    'es2016',
                    'es2017',
                    'stage-3',
                ],
            },
        },
        {
            loader: 'ejs-loader',
        },
    ],
};

This is what I want and I get:

ERROR in ./src/table/row.html
Module build failed: SyntaxError: 'with' in strict mode (5:0)

  3 | var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
  4 | function print() { __p += __j.call(arguments, '') }
> 5 | with (obj) {
    | ^
  6 | 
  7 |  _.each(tableKeys, (k) => { ;
  8 | __p += '\n  <td>' +

If I remove the babel part completely it works but with ES6 code not transpiled:

{
    test: /\.html$/,
    use: [
        {
            loader: 'ejs-loader',
        },
    ],
};

I have also seen this question about removing strict mode and have tried several things related to es2015 applying strict. I think I have tried every solution in that question including hotpatching workaround and I still get the same error. In the end i tried this:

{
    test: /\.html$/,
    use: [
        {
            loader: 'babel-loader',
            query: {
                presets: [
                ],
            },
        },
        {
            loader: 'ejs-loader',
        },
    ],
};

I though this should do the same as without the bable pass, but I get the same error here. Somehow without any presets I get the same error.

EDIT

I have also tried to work around it by passing variable in query and I have made that work with ejs-loader, however I'm not looking for a solution where all the templates need changing.

I have made a repository which illustrates the problem. The master branch has babel-loader commented out and works with with while the transpile branch will have compile errors even though { modules: false } is passed and I have a branch called transpile-no-presets where all presets in package.json is removed and the error is still showing.

like image 264
Sylwester Avatar asked May 23 '17 12:05

Sylwester


1 Answers

By default Underscore .template put your data in the scope using a with statement. See Underscore docs.

I think the cleanest solution is to instruct your ejs-loader to not compile to with statements but to use a temporary variable instead:

{
    loader: 'ejs-loader?variable=data',
},

...and change your templates to reference the temporary variable.

From:

<ul>
  <% _.each(test, (n) => { %>
    <li>This is line number <%- n %></li>
  <% }); %>
</ul>

to:

<ul>
  <% _.each(data.test, (n) => { %>
    <li>This is line number <%- n %></li>
  <% }); %>
</ul>
like image 52
Andrea Carraro Avatar answered Jan 10 '23 15:01

Andrea Carraro