3

I already made this a github issue, but I am suspecting there might be something trivial, that I just don't know about.

I would really appreciate some input to help me with the debuging.

Demo:

https://github.com/andrasna/html-ejs-webpack-config-issue-demo

index.ejs

<% const title = 'Hello' %>

<%- include('partial') -%>

<h1><%= `${title} World` %></h1> 

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.ejs',
    })
  ]
}

Expected behaviour

I am trying to include one EJS file into another, as per documentation:

https://ejs.co/#docs

<%- include('header'); -%>
<h1>
  Title
</h1>
<p>
  My page
</p>
<%- include('footer'); -%>

What I would expect, is for the HTML within partial.ejs to be included in the index.ejs file.

Current behaviour

I get "Error: Child compilation failed" (see full error message below).

However, EJS gets compiled if I remove the line with the include in index.ejs. Which is why I think the problem is specific to includes.

Any ideas?

Error message

> npm start

> html-ejs-webpack-config-issue-demo@1.0.0 start /Users/user/Dev/html-ejs-webpack-config--issue-demo
> webpack-dev-server --mode development

ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /Users/user/Dev/html-ejs-webpack-config--issue-demo
✖ 「wdm」: Hash: f9f8666f87ab7acd22cd
Version: webpack 4.41.2
Time: 595ms
Built at: 19/10/2019 15:34:18
     Asset      Size  Chunks             Chunk Names
index.html  1.72 KiB          [emitted]  
   main.js   360 KiB    main  [emitted]  main
Entrypoint main = main.js
[0] multi (webpack)-dev-server/client?http://localhost:8080 ./src 40 bytes {main} [built]
[./node_modules/ansi-html/index.js] 4.16 KiB {main} [built]
[./node_modules/ansi-regex/index.js] 135 bytes {main} [built]
[./node_modules/html-entities/index.js] 231 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/strip-ansi/index.js] 161 bytes {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost:8080] (webpack)-dev-server/client?http://localhost:8080 4.29 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.51 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.53 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/createSocketUrl.js] (webpack)-dev-server/client/utils/createSocketUrl.js 2.89 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/log.js] (webpack)-dev-server/client/utils/log.js 964 bytes {main} [built]
[./node_modules/webpack-dev-server/client/utils/reloadApp.js] (webpack)-dev-server/client/utils/reloadApp.js 1.59 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/sendMessage.js] (webpack)-dev-server/client/utils/sendMessage.js 402 bytes {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./src/index.js] 0 bytes {main} [built]
    + 18 hidden modules

ERROR in   Error: Child compilation failed:
  Module build failed (from ./node_modules/html-webpack-plugin/lib/loader.js):
  SyntaxError: Unexpected token )

  - Function

  - lodash.js:14870 
    [html-ejs-webpack-config--issue-demo]/[lodash]/lodash.js:14870:16

  - lodash.js:473 apply
    [html-ejs-webpack-config--issue-demo]/[lodash]/lodash.js:473:27

  - lodash.js:15254 
    [html-ejs-webpack-config--issue-demo]/[lodash]/lodash.js:15254:16

  - lodash.js:475 apply
    [html-ejs-webpack-config--issue-demo]/[lodash]/lodash.js:475:27

  - lodash.js:6563 
    [html-ejs-webpack-config--issue-demo]/[lodash]/lodash.js:6563:16

  - lodash.js:14869 Function.template
    [html-ejs-webpack-config--issue-demo]/[lodash]/lodash.js:14869:20


  - SyntaxError: Unexpected token )

  - compiler.js:79 childCompiler.runAsChild
    [html-ejs-webpack-config--issue-demo]/[html-webpack-plugin]/lib/compiler.js:79:16

  - Compiler.js:343 compile
    [html-ejs-webpack-config--issue-demo]/[webpack]/lib/Compiler.js:343:11

  - Compiler.js:681 hooks.afterCompile.callAsync.err
    [html-ejs-webpack-config--issue-demo]/[webpack]/lib/Compiler.js:681:15


  - Hook.js:154 AsyncSeriesHook.lazyCompileHook
    [html-ejs-webpack-config--issue-demo]/[tapable]/lib/Hook.js:154:20

  - Compiler.js:678 compilation.seal.err
    [html-ejs-webpack-config--issue-demo]/[webpack]/lib/Compiler.js:678:31


  - Hook.js:154 AsyncSeriesHook.lazyCompileHook
    [html-ejs-webpack-config--issue-demo]/[tapable]/lib/Hook.js:154:20

  - Compilation.js:1423 hooks.optimizeAssets.callAsync.err
    [html-ejs-webpack-config--issue-demo]/[webpack]/lib/Compilation.js:1423:35



Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [./node_modules/html-webpack-plugin/lib/loader.js!./index.ejs] 922 bytes {0} [built] [failed] [1 error]

    ERROR in ./index.ejs (./node_modules/html-webpack-plugin/lib/loader.js!./index.ejs)
    Module build failed (from ./node_modules/html-webpack-plugin/lib/loader.js):
    SyntaxError: Unexpected token )
        at Function (<anonymous>)
        at /Users/user/Dev/html-ejs-webpack-config--issue-demo/node_modules/lodash/lodash.js:14870:16
        at apply (/Users/user/Dev/html-ejs-webpack-config--issue-demo/node_modules/lodash/lodash.js:473:27)
        at /Users/user/Dev/html-ejs-webpack-config--issue-demo/node_modules/lodash/lodash.js:15254:16
        at apply (/Users/user/Dev/html-ejs-webpack-config--issue-demo/node_modules/lodash/lodash.js:475:27)
        at /Users/user/Dev/html-ejs-webpack-config--issue-demo/node_modules/lodash/lodash.js:6563:16
        at Function.template (/Users/user/Dev/html-ejs-webpack-config--issue-demo/node_modules/lodash/lodash.js:14869:20)
        at Object.module.exports (/Users/user/Dev/html-ejs-webpack-config--issue-demo/node_modules/html-webpack-plugin/lib/loader.js:28:22)
ℹ 「wdm」: Failed to compile.

  • can you update the repo so that the solution that worked for you can be seen in a commit? the answers below didn't work for me – demiculus Dec 15 '19 at 09:41

2 Answers2

-1

use the ejs-compiled-loader with the HtmlWebpackPlugin

npm install --save-dev ejs-compiled-loader

change webpack.config.js to:

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: '!!ejs-compiled-loader!index.ejs', //Here is the Loader plugged in
    })
  ]
}

(as described here)

Then alter your template to valid EJS. HtmlWebpackPlugin says: "By default (if you don't specify any loader in any way) a fallback lodash loader kicks in." It renders the template with lodash as a minimalistic loader. This is why your errors come from lodash.js .

index.ejs:

<% title = 'Hello' %>

<%- include partial -%>

<h1><%= title%> World</h1> 

Then npm start and your fresh compiled "Lorem Ipsum ...Hello World" will be served on your localhost.

Or npx webpack --mode=development to get your 'dist/index.html' to enjoy the source :)

tweini
  • 806
  • 8
  • 12
  • 1
    "Then alter your template to valid EJS." It is already valid EJS, and it compiles without `include`, because html-webpack-plugin uses an ejs fallback loader. Still, looks like "ejs-compiled-loader" works. But the repository doesn't seem to be maintained anymore, and unlike the default ejs fallback loader, it fails to compile valid JS (like template literals). –  Oct 24 '19 at 17:31
  • 2
    You are right. The standalone compilation of you template with ejs.compile works fine. The package trapped me using v1.x of the ejs-compiled-loader and therefore EJS v1. (To use v2.x you need to install ejs-compiled-loader-webpack4 which refers to the same repo (https://github.com/bazilio91/ejs-compiled-loader) but installs the v2.x branch. Here the compilation fails with an error "include is not a function" which has been mentioned in this repo https://github.com/testerum/ejs-compiled-loader-webpack4-nodeps and isn't fixed. I am still looking at the source where the error occurs. Wish me luck – tweini Oct 24 '19 at 18:22
  • npm ERR! enoent Error while executing: npm ERR! enoent undefined ls-remote -h -t https://github.com/nemanjan00/ejs.git – zipper Feb 05 '20 at 07:43
  • ejs-compiled-loader is not maintained anymore. AFAIS it also misses template parameter management. – Marco Faustinelli Sep 15 '21 at 08:54
-1

Issue with your use-case is your webpack file you are not using ejs compiler.

I made some changes and refactor some bad practice you had.

final code you can find below:

https://gitlab.com/akhileshcoder/ejs-webpack-starter

Now your webpack.config looks like below (as a task/project handler for client)

module.exports = {
  devServer: {
    inline:true,
    port: 8080
  },
  entry: './src/index.js',
  output: {
    path: __dirname + '/public/dist',
    filename: 'bundle.js',
    publicPath: '/public/dist',
    library: 'bundle',
    libraryTarget: 'var'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['es2015']
            }
          }
        ]
      }
    ]
  }
};

and ejb gets render on express as below:

app.set('views', path.join(__dirname, '../views'));
app.set('view engine', 'ejs');
app.get('/', function(req, res, next) {
  res.render('index', {title: 'Hello World'});
});
Akhilesh Kumar
  • 9,085
  • 13
  • 57
  • 95
  • "you are not using ejs compiler" As I pointed out, it does compile without `include`. This is, because html-webpack-plugin uses an ejs fallback loader: https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md#3-setting-a-loader-using-the-moduleloaders-syntax "I made some changes and refactor some bad practice you had." It would help, if you could point out the bad practices. The repository I shared only includes the bare minimum, to reproduce the issue. –  Oct 24 '19 at 17:08
  • 1
    Thanks for the example, though it replaces webpack-dev-server with express, so the example lacks webpack-dev-server features I previously had, like hot-reloading, and running in-memory. –  Oct 24 '19 at 19:12