如何在webpack中使用ejs templates/partials?

rhfm7lfc  于 12个月前  发布在  Webpack
关注(0)|答案(1)|浏览(104)

我尝试使用Express和ejs创建一个全栈应用程序,并使用webpack捆绑客户端资产。当我设置它没有ejs时,它都工作得很好。当我尝试将index.html更改为index.ejs时,问题就来了,它使用部分头部,页脚等。最终这将是一个多页应用程序,这就是我使用ejs模板的原因。
我试过使用ejs-loader(https://www.npmjs.com/package/ejs-loader),ejs-compiled-loader(https://github.com/bazilio91/ejs-compiled-loader)和ejs-html-loader(https://www.npmjs.com/package/ejs-html-loader),但没有任何乐趣。
任何帮助都将不胜感激。我相信这真的很简单,但对于我的生活,我不能解决如何将ejs连接到webpack并使模板工作。
我已经在下面包含了使用template.html的代码。我需要知道如何将其更改为使用index.ejs?
我的文件结构看起来像这样:

  • --dist(从webpack输出)
  • --src(包含index.ejs)
  • -partials(包含index.ejs的partials)
  • app.js
  • webpack.common.js
  • webpack.dev.js
  • webpack.prod.js
  • package.json等。

Index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
 <% include partials/head %> 
</head>
<body>
<main>
<% include partials/main %>
</main>
<% include partials/footer %>
</body>
</html>

字符串
我的配置文件如下所示(我只包含了两个合并的构建图):
webpack.common.js

const path = require("path")

module.exports = {
  entry: {
    main: "./src/index.js",
    vendor: "./src/vendor.js"
  },
  module: {
    rules: [
      {
        test: /\.html$/,
      use: ["html-loader"]
      },
      {
        test: /\.(svg|png|jpg|gif)$/,
        use: {
          loader: "file-loader",
          options: {
            name: "[name].[hash].[ext]",
            outputPath: "imgs"
          }
        }
      }      
    ]
  },
}


webpack.prod.js

const path = require("path")
const common = require("./webpack.common")
const merge = require("webpack-merge")
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = merge(common, {
  mode: "production",
  output: {
    filename: "[name].[contentHash].js",
    path: path.resolve(__dirname, "dist")
  },
  optimization: {
    minimizer: [
    new OptimizeCssAssetsPlugin(),
    new TerserPlugin(),
    new HtmlWebpackPlugin({
      template: "./src/template.html",
      minify: {
        removeAttributeQuotes: true,
        collapseWhitespace: true,
        removeComments: true,
      }
    })]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].[contentHash].css",
    }),
    new CleanWebpackPlugin(),
  ],
  module: {
    rules: [{
      test: /\.scss$/,
      use: [
        MiniCssExtractPlugin.loader,
        "css-loader",
        "sass-loader"
      ]
    }]
  }
});


这是我的第一篇文章,如果我没有包括任何重要的东西,请让我知道!
谢谢你,谢谢

g9icjywg

g9icjywg1#

在Webpack 5中,我通过利用html-loaderpreprocessor选项来使用EJS模板。
有关preprocessor选项的详细信息,请参阅此处。
多页面应用程序的简单实现是:

  • 1.安装包:

npm i html-loader ejs html-webpack-plugin -D

  • !注意使用html-loader将禁用html-loader-plugin使用的默认加载器。*
  • 2.Webpack配置(html-webpack-plugin-定义页面,以及页面的具体参数和标题。模板路径必须是绝对路径。
module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './src/index.ejs'), // absolute path
      filename: 'index.html',
      templateParameters: {
        bodyClass: 'page-index'
      },
      title: 'Index | Webpack Starter',
    }),
   new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './src/about.ejs'), // absolute path
      filename: 'about.html',
      templateParameters: {
        bodyClass: 'page-about'
      },
      title: 'About | Webpack Starter',
    }),
  ]
}

字符串

  • 3.Webpack config(html-loader-设置html-loader,带有preprocessor选项。每个partial都应该作为依赖添加到Webpack编译器中。另外,我们可以将htmlWebpackPlugin.options作为模板参数传递。
const ejs = require('ejs');
const fs = require('fs');

module.exports = {
 // ...
 module: {
   rules: [
      {
        test: /\.ejs$/i,
        loader: 'html-loader',
        options: {
          preprocessor: (content, loaderContext) => {
            try {
              const templatePath = path.resolve(__dirname, './src/index.ejs');

              // trigger re-compile if partial has changed
              // see: https://github.com/webpack-contrib/html-loader/issues/386
              const partialsPath = path.resolve(__dirname, './src/partials');
              fs.readdirSync(partialsPath).forEach((file) => {
                if (file.endsWith('.ejs')) {
                  const filePath = `${partialsPath}/${file}`;
                  loaderContext.addDependency(filePath);
                }
              });

              const templateParameters = {
                // ... add your data here
              };

              // OPTIONAL: expose htmlWebpackPlugin object in EJS templates
              const currentHtmlWebpackPlugin = loaderContext._compiler.options.plugins.filter(
                (plugin) =>
                  typeof plugin === 'object' &&
                  plugin.options &&
                  plugin.options.template &&
                  plugin.options.template === loaderContext.resourcePath,
              )[0];

              if (typeof currentHtmlWebpackPlugin === 'object') {
                Object.assign(templateParameters, {
                  htmlWebpackPlugin: currentHtmlWebpackPlugin,
                });

                if (typeof currentHtmlWebpackPlugin.options.templateParameters !== 'function') {
                  Object.assign(templateParameters, {
                    ...currentHtmlWebpackPlugin.options.templateParameters,
                  });
                }
              }

              return ejs.render(content, templateParameters, { filename: templatePath });
            } catch (error) {
              loaderContext.emitError(error);

              return content;
            }
          },
        },
      },

    // other rules
   ]
 }
}

  • 4.Webpack Dev Server-设置dev-server来监视ejs文件的更改:
devServer: {
    hot: true,
    watchFiles: ['./src/**/*.ejs'],
  },


示例项目:https://stackblitz.com/edit/github-7dw627?file=webpack%2Fwebpack.config.common.js

相关问题