Webpack:编译文件夹但保留单独的文件吗?

时间:2019-03-26 18:27:07

标签: javascript webpack yarnpkg nunjucks

我有Webpack配置,可将nunjuck文件编译为html文件。但是,我必须手动指定每个文件的输入和输出。我不知道如何1)读取给定文件夹中的所有文件,以及2)将分离编译后的文件输出到另一个文件夹中,如下所示:

src/file1.njk -> dist/file1.html
src/file2.njk -> dist/file2.html
...

这是我的配置文件:

const path = require("path");
var HtmlWebpackPlugin = require("html-webpack-plugin");
var glob_entries = require("webpack-glob-folder-entries");

// Optional, but highly recommended. Create a returnEntries:
// Webpack doesn't support glob paths. For the nunjucks-html-loader
// we need each path to be specified for it to work (YES, even subdirectories!)

function returnEntries(globPath) {
  let entries = glob_entries(globPath, true);
  let folderList = new Array();
  for (let folder in entries) {
    folderList.push(path.join(__dirname, entries[folder]));
  }
  return folderList;
}

module.exports = {
  entry: "./src/app.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist")
  },
  plugins: [
    // HtmlWebpackPluginConfig
    new HtmlWebpackPlugin({
      filename: "index.html",
      inject: "body",
      template: "nunjucks-html-loader!./src/pages/index.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "1-categorize-devices.html",
      inject: "body",
      template: "nunjucks-html-loader!./src/pages/1-categorize-devices.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "2-split-to-triggers-vs-actors.html",
      inject: "body",
      template:
        "nunjucks-html-loader!./src/pages/2-split-to-triggers-vs-actors.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "3-generate-all-combinations.html",
      inject: "body",
      template:
        "nunjucks-html-loader!./src/pages/3-generate-all-combinations.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "4-rate-all-combinations.html",
      inject: "body",
      template: "nunjucks-html-loader!./src/pages/4-rate-all-combinations.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "5-cluster-useful-combinations.html",
      inject: "body",
      template:
        "nunjucks-html-loader!./src/pages/5-cluster-useful-combinations.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "6-scenes-for-given-packages.html",
      inject: "body",
      template:
        "nunjucks-html-loader!./src/pages/6-scenes-for-given-packages.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "7-design-templates.html",
      inject: "body",
      template: "nunjucks-html-loader!./src/pages/7-design-templates.njk"
    }),
    new HtmlWebpackPlugin({
      filename: "8-functional-prototype.html",
      inject: "body",
      template: "nunjucks-html-loader!./src/pages/8-functional-prototype.njk"
    })
  ],
  module: {
    rules: [
      {
        test: /\.(scss)$/,
        use: [
          {
            // Adds CSS to the DOM by injecting a `<style>` tag
            loader: "style-loader"
          },
          {
            // Interprets `@import` and `url()` like `import/require()` and will resolve them
            loader: "css-loader"
          },
          {
            // Loader for webpack to process CSS with PostCSS
            loader: "postcss-loader",
            options: {
              plugins: function() {
                return [require("autoprefixer")];
              }
            }
          },
          {
            // Loads a SASS/SCSS file and compiles it to CSS
            loader: "sass-loader"
          }
        ]
      },
      {
        // HTML LOADER
        // Super important: We need to test for the html
        // as well as the nunjucks files
        test: /\.html$|njk|nunjucks/,
        use: [
          "html-loader",
          {
            loader: "nunjucks-html-loader",
            options: {
              // Other super important. This will be the base
              // directory in which webpack is going to find
              // the layout and any other file index.njk is calling.
              //  searchPaths: [...returnEntries('./src/pages/**/')]
              // Use the one below if you want to use a single path.
              searchPaths: ["./src/pages"]
            }
          }
        ]
      }
    ]
  }
};

如您所见,我一直在重复new HtmlWebpackPlugin()并且不知道如何使操作自动化。

非常感谢您。

2 个答案:

答案 0 :(得分:1)

根据HtmlWebpackPlugin文档,您实际上正在做的是recommended approach(显然很烂的 )。

但是,您可以像编写一个助手函数那样代替手动逐一列出它们,该函数将包含要转换的文件列表(通过glob通配符说)并输出数组。 HtmlWebpackPlugin条说明,您可以直接将其输入webpack配置。

这只是JS。 Webpack配置只是一个NodeJS脚本。您可以做任何您喜欢的事情。

答案 1 :(得分:1)

类似这样的事情应该可以解决:

 const glob = require('glob');


 const pages = glob.sync('**/*.njk', {
    cwd: path.join(__dirname, 'src/pages/'),
    root: '/',
  }).map(page =>
    new HtmlWebpackPlugin({
      filename: page.replace('njk', 'html'),
      template: `src/pages/${page}.njk`,
    }));

然后使用它:

plugins: [
  ...pages,