Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using es6 template string break the html file build #950

Closed
tommytroylin opened this issue May 14, 2018 · 8 comments · Fixed by #953
Closed

using es6 template string break the html file build #950

tommytroylin opened this issue May 14, 2018 · 8 comments · Fixed by #953

Comments

@tommytroylin
Copy link
Contributor

Description

This may be something related when html-webpack-html processing html template with lodash/template.

https://github.com/jantimon/html-webpack-plugin/blob/master/lib/loader.js#L30-L34

Error Message & Stack Trace

ERROR in Template execution failed: ReferenceError: hello is not defined

ERROR in   ReferenceError: hello is not defined

  - loader.js:6 eval
    [index.html?.]/[html-webpack-plugin]/lib/loader.js:6:10

  - loader.js:11 module.exports
    [index.html?.]/[html-webpack-plugin]/lib/loader.js:11:3

  - index.js:284 Promise.resolve.then
    [template-react-typescript]/[html-webpack-plugin]/index.js:284:18


  - next_tick.js:188 process._tickCallback
    internal/process/next_tick.js:188:7

Config

Copy the relevant section from webpack.config.js:

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html"
    }),
  ]
}

Copy your template file:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>
        <%= htmlWebpackPlugin.options.title %>
    </title>
    <script>
        const hello = 'hello';
        const world = 'world'
        console.log(`${hello} ${world}`);  // ~this line~
    </script>
</head>

<body>
    <div id="app"></div>
    
</body>

</html>

Environment

node 8.11.1
macOS 10.13
npm 6
webpack 4.7
html-webpack-plugin 3.2.0
@jantimon
Copy link
Owner

Thanks for reporting this issue - could you please add a console.log statement here and post the content of source?

https://github.com/jantimon/html-webpack-plugin/blob/master/index.js#L245

@tommytroylin
Copy link
Contributor Author

Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [0] (webpack)/buildin/module.js 546 bytes {0} [built]
    [1] (webpack)/buildin/global.js 492 bytes {0} [built]
    [3] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html 674 bytes {0} [built]

it's a pretty long output and I guess what you need is module[3].
BTW, I've already run npm update so webpack should be 4.8.3 now.

The output is

(function(module, exports, __webpack_require__) {

var _ = __webpack_require__(2);module.exports = function (templateParams) { with(templateParams) {return (function(data) {
var __t, __p = '';
__p += '<!DOCTYPE html>\n<html lang="en">\n\n<head>\n    <meta charset="UTF-8">\n    <title>\n        ' +
((__t = ( htmlWebpackPlugin.options.title )) == null ? '' : __t) +
'\n    </title>\n    <script>\n        const hello = \'hello\';\n        const world = \'world\'\n        console.log(`' +
((__t = (hello)) == null ? '' : __t) +
' ' +
((__t = (world)) == null ? '' : __t) +
'`);  // ~this line~\n    </script>\n</head>\n\n<body>\n    <div id="app"></div>\n    \n</body>\n\n</html>\n';
return __p
})();}}

})

em... seems it unexpectedly processes ES6 template strings as same as <%= %> bindings.

@jantimon
Copy link
Owner

Nice 👍 thanks for analyzing.
This is exactly the reason why it is broken.
The transformation is done here:

const template = _.template(source, _.defaults(options, { variable: 'data' }));

Do you have any idea what might be the reason?

tommytroylin added a commit to tommytroylin/html-webpack-plugin that referenced this issue May 17, 2018
Only transpile EJS style `<%= name %>`, Close jantimon#950
@tommytroylin
Copy link
Contributor Author

I've find a lodash issue here lodash/lodash#399 (comment)
So this behavior is definitely caused by lodash/template which keeps ES6 template delimiters working on default.

solution could be simply add a default { interpolate: /<%=([\s\S]+?)%>/g } option to:

const template = _.template(source, _.defaults(options, { variable: 'data' }));

@tommytroylin
Copy link
Contributor Author

BTW, Although in all docs it doesn't encourage users to use ${} syntax, this change may break some users' templates & projects potentially.

I suggest a semver-minor change and document it on top of changelog and readme

@jantimon
Copy link
Owner

Hey @tommytroylin
thank you so much for the fix - I will merge it very soon!
As it sounds like a breaking change I would prefer to merge it into the next major version.
I hope that's okay for you

jantimon pushed a commit that referenced this issue May 18, 2018
Only transpile EJS style `<%= name %>`, Close #950
@jantimon
Copy link
Owner

jantimon pushed a commit that referenced this issue May 18, 2018
Only transpile EJS style `<%= name %>`, Close #950

BREAKING CHANGE: Template strings inside templates are now disabled by default
jantimon pushed a commit that referenced this issue May 19, 2018
Only transpile EJS style `<%= name %>`, Close #950

BREAKING CHANGE: Template strings inside templates are now disabled by default
jantimon pushed a commit that referenced this issue Jun 3, 2018
Only transpile EJS style `<%= name %>`, Close #950

BREAKING CHANGE: Template strings inside templates are now disabled by default
@lock
Copy link

lock bot commented Jun 17, 2018

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 17, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants