6

I'm trying to configure webpack with my website using node js, I'm using also ejs as a view. I have tried with many ways to handle the ejs in my webpack, but till now I didn't get success.

const path = require('path')
const nodeExternals = require('webpack-node-externals')

module.exports = (env, argv) => {
  return ({
    entry: {
      server: './src/app.js',
    },
    output: {
      path: path.join(__dirname, 'dist'),
      publicPath: '/',
      filename: 'main.js'
    },
    mode: argv.mode,
    target: 'node',
    node: {
      // Need this when working with express, otherwise the build fails
      __dirname: true,
      __filename: true,
    },
    externals: [nodeExternals()], // Need this to avoid error when working with Express
    module: {
      rules: [
        {
          // Transpiles ES6-8 into ES5
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: "babel-loader"
          }
        },
        {
         test: /\.ejs$/,
         loader: 'ejs-loader',
         options: {
           esModule: false
         }
       }
      ]
    }
  })
}

when I use HtmlWebPackPlugin I get some errors because of data inside <%- %> it's like he didn't know this data where comes from. like for example, <%- include('partials/head.ejs') %>. is there a way to handle my views as ejs using webpack?

Nouh Belahcen
  • 774
  • 1
  • 11
  • 36

5 Answers5

3

I know this has been asked a few months ago. But for those who come across this issue like I have, this is how I got this to work. Assuming your using webpack 4.

If you have not already install html-webpack-plugin

Most importantly to help solve the issue install raw-loader

add the following to your webpack config

new HtmlWebpackPlugin({
  template: '!!raw-loader!./src/views/pages/<file-name-here>.ejs',
  filename: 'index.ejs',
  chunks: ['main', 'owl_carousel']
})

This is where the magic is. when including the template path make sure to include !!raw-loader! followed by the relative path.

raw-loader makes it so when html plugin creates the file it ignores the special syntax ejs uses. It is basically like "hey plugin ignore whatever I put here and just get me my file".

Jose Munoz
  • 56
  • 1
  • 3
1

As @JRichardsz explained, You won't need Webpack explicitly to use EJS templates in your NodeJS project.
Also, It simply bundles up the EJS template (code) implicitly.
Try to bundle up your files with latest Webpack.js using below command to install:

npm install --save-dev webpack

Also, try this code with a little fix:

module.exports = (env, argv) => {
  return ({
    output: {
          path: path.resolve(__dirname, 'dist'),
          publicPath: '/',
          filename: 'main.js'
        }
        ...
        // in case, all of this doesn't work. Then, explicitly whitelist EJS using regex
        ...
        nodeExternals({
            whitelist: [/\.(?|ejs)$)],
        }),
        ...
    })
  }
kartik tyagi
  • 6,256
  • 2
  • 14
  • 31
0

If you want to use ejs for nodejs projects, you don't need webpack. Webpack is commonly used for client side rendering like angular, vue, react, etc

Check this: Which command should I use to minify and optimize nodejs express application? to view some ways to optimize your static js files used in ejs or another nodejs server rendering framework.

Basic structure for ejs projects is:

|____
|____server.js
|____views
| |____hello.ejs
|____package.json

hello.ejs a simple and plain template in which you can use any of ejs code like your

<%- include('partials/head.ejs') %>

As you can see, you don't need webpack to run ejs apps.

Check these samples:

JRichardsz
  • 14,356
  • 6
  • 59
  • 94
  • I need to minify my CSS and remove duplicate CSS... I can use webpack for node js you can check https://github.com/bengrunfeld/expack – Nouh Belahcen Jun 24 '20 at 18:35
  • In your anwser you mentioned `<%- include('partials/head.ejs') %>`. But ejs is not present in your github repository. To use ejs, you don't need webpack. Maybe is possible, but is not required. Css minification should be another question. – JRichardsz Jun 25 '20 at 03:06
0

You would need to make bundle of the EJS.
Try below commands:

module.exports = (env, argv) => {
  return ({
    output: {
          path: './dist',
          publicPath: '/',
          filename: 'main.js'
        }
    })
  }
0

copy-webpack-plugin worked perfectly

  plugins: [
    new webpack.ProgressPlugin(),
    new CopyWebpackPlugin({
      patterns: [
        {from: "src/views", to: "views"}
      ]
    })
Jim Rand
  • 221
  • 1
  • 5