“This is the fifth day of my participation in the First Challenge 2022. For details: First Challenge 2022”

preface

Earlier, I wrote a webPack template. I usually use it when I’m writing chestnuts or a few pages. If the template needs multiple pages, you need to manually configure entry and HtmlWebpackPlugin in the webpack.config.ts file, which is a bit of a hassle.

thinking

The pages in our project are stored in SRC /pages/*.html, and we can search the HTML files in this folder. We can use the.sync method in the Glob package in Node to match and search the files we want. An entrys object is automatically generated and assigned to the entry property in the webpack.config.ts file. HtmlWebpackPlugin similarly.

Install the glob

pnpm add glob
Copy the code

Creating a utility class

Create a uilts/index.ts file in the SRC directory and import the required dependency packages (glob, PATH, htMl-webpack-plugin).

The SRC └ ─ uilts └ ─ index. TsCopy the code
// uilts/index.ts
import Glob from 'glob';
import path from 'path';
import HtmlWebpackPlugin from 'html-webpack-plugin';
Copy the code

getEntry

Encapsulate the getEntry method to search for the script files introduced by the page, which requires passing in a matching rule, the path, using the.sync method in the glob package, which returns the matched data set. The file name and path are concatenated into the key:value required by the entry object. Finally, getEntry returns an object.

export function getEntry(globPath: string) :entryObj {
  const entries: entryObj = { main: './src/main.ts' };
  Glob.sync(`${globPath}.ts`).forEach((entry: string) = > {
    const basename: string = path.basename(entry, path.extname(entry));
    const pathname: string = path.dirname(entry);
    entries[basename] = `${pathname}/${basename}`;
  });
  return entries;
}
Copy the code

getHtmlWebpackPlugin

Encapsulate the getHtmlWebpackPlugin method, which is used to output all matched HtmlWebpackPlugin objects. It also passes a matching rule that matches all *.html files,

export function getHtmlWebpackPlugin(globPath: string) :HtmlWebpackPlugin[] {
  const htmlPlugins: HtmlWebpackPlugin[] = [];
  Glob.sync(`${globPath}.html`).forEach((entry: string) = > {
    const basename: string = path.basename(entry, path.extname(entry));
    const pathname: string = path.dirname(entry);
    htmlPlugins.push(new HtmlWebpackPlugin({
      title: basename,
      filename: `${basename}.html`.template: `${pathname}/${basename}.html`.chunks: [basename, 'main'].minify: true,})); });return htmlPlugins;
}
Copy the code

Secondary packaging

Once you have these two methods, you can wrap the two methods into a getPages function and call it in webpack.config.ts to get the entry object and the htmlPlugins array directly.

interface getPagesType {
  entries: entryObj,
  htmlPlugins: HtmlWebpackPlugin[]
}

export function getPages(pagePath: string) :getPagesType {
  const entries: entryObj = getEntry(pagePath);
  const htmlPlugins: HtmlWebpackPlugin[] = getHtmlWebpackPlugin(pagePath);
  return {
    entries,
    htmlPlugins,
  };
}
Copy the code

application

Use the getPages function in webpack.config.ts.

The getPages function is introduced to pass in the path of the page in the project. Data objects returned using ES6’s deconstruction prize.

// webpack.config.ts
const { entries, htmlPlugins } = getPages('./src/pages/**/*');

const config: Configuration = {
  mode: 'development'.entry: entries,
  // ...
  plugins: [
    ...htmlPlugins,
  ],
};
Copy the code