如何使用SCSS、PurgeCSS和LiveServer设置自定义ESBuild?

15

背景:

我有一个Webpack设置,用于使用PurgeCSS预处理SCSS,并带有esbuild-loader的实时HMR服务器来加快Webpack编译速度,但即使如此,我的编译时间仍然很慢,我想使用ESBuild的原始速度,完全删除Webpack设置。

ESBuild的基本设置很简单,您可以使用npm安装esbuild并在package.json中添加以下代码:

{
  ...
  "scripts": {
    ...
    "watch": "esbuild --bundle src/script.js --outfile=dist/script.js --watch"
  },
  ...
}

使用以下命令运行:

npm run watch
这个单行配置将打包您的脚本和样式(您可以在 script.js 中导入 style.css),并输出文件到 dist 目录,但这不允许对 ESBuild 进行高级配置,例如为您的样式表和脚本文件输出不同的名称或使用插件。

问题:

  1. 如何使用外部配置文件配置 ESBuild?
  2. ESBuild 不支持 SCSS。如何配置外部插件,比如 esbuild-sass-plugin ,甚至如何设置 PostCSS 及其插件,例如 Autoprefixer
  3. 如何设置自动重建的开发服务器?
  4. 如何设置 PurgeCSS?
3个回答

38

解决方案:

1. 如何使用外部配置文件来配置 ESBuild?

  1. 在根目录下创建一个名为esbuild.mjs的新文件,并将以下内容添加到其中:
import esbuild from "esbuild";

esbuild
    .build({
        entryPoints: ["src/styles/style.css", "src/scripts/script.js"],
        outdir: "dist",
        bundle: true,
        plugins: [],
    })
    .then(() => console.log("⚡ Build complete! ⚡"))
    .catch(() => process.exit(1));

请在您的 package.json 中添加以下代码:
{
    ...
    "scripts": {
        ...
        "build": "node esbuild.mjs"
    },
...
}
  1. 使用npm run build命令运行构建,这将打包您的样式表和脚本,并将它们输出到dist目录中。
  2. 如需了解更多详细信息和/或添加自定义构建选项,请参阅ESBuild的构建API文档

2. ESBuild不支持SCSS。如何配置外部插件,例如esbuild-sass-plugin,以及如何设置PostCSS和Autoprefixer等插件?

  1. 安装npm依赖项:npm i -D esbuild-sass-plugin postcss autoprefixer
  2. 将您的esbuild.mjs编辑为以下代码:
import esbuild from "esbuild";
import { sassPlugin } from "esbuild-sass-plugin";
import postcss from 'postcss';
import autoprefixer from 'autoprefixer';

// Generate CSS/JS Builds
esbuild
    .build({
        entryPoints: ["src/styles/style.scss", "src/scripts/script.js"],
        outdir: "dist",
        bundle: true,
        metafile: true,
        plugins: [
            sassPlugin({
                async transform(source) {
                    const { css } = await postcss([autoprefixer]).process(source);
                    return css;
                },
            }),
        ],
    })
    .then(() => console.log("⚡ Build complete! ⚡"))
    .catch(() => process.exit(1));

3. 如何设置具有自动重建功能的开发服务器?

  1. ESBuild 在这方面有一个限制,您只能传递 watch: true运行其服务器它不允许同时使用两者
  2. ESBuild 还有另一个限制,它不像 Webpack 一样支持 HMR
  3. 因此,为了应对这两个限制并仍然允许服务器,我们可以使用 Live Server。使用 npm i -D @compodoc/live-server 安装它。
  4. 在根目录下创建一个名为:esbuild_watch.mjs 的新文件,并添加以下内容:
import liveServer from '@compodoc/live-server';
import esbuild from 'esbuild';
import { sassPlugin } from 'esbuild-sass-plugin';
import postcss from 'postcss';
import autoprefixer from 'autoprefixer';

// Turn on LiveServer on http://localhost:7000
liveServer.start({
    port: 7000,
    host: 'localhost',
    root: '',
    open: true,
    ignore: 'node_modules',
    wait: 0,
});

// Generate CSS/JS Builds
esbuild
    .build({
        logLevel: 'debug',
        metafile: true,
        entryPoints: ['src/styles/style.scss', 'src/scripts/script.js'],
        outdir: 'dist',
        bundle: true,
        watch: true,
        plugins: [
            sassPlugin({
                async transform(source) {
                    const { css } = await postcss([autoprefixer]).process(
                        source
                    );
                    return css;
                },
            }),
        ],
    })
    .then(() => console.log('⚡ Styles & Scripts Compiled! ⚡ '))
    .catch(() => process.exit(1));
  1. 编辑你的 package.json 中的脚本
{
    ...
    "scripts": {
        ...
        "build": "node esbuild.mjs",
        "watch": "node esbuild_watch.mjs"
    },
...
}
  1. 运行构建请使用以下命令npm run build
  2. 要运行自动重建的dev服务器,请运行npm run watch。 这是一种“hacky”的做法,但可以完成一个公平的工作。

4.如何设置PurgeCSS?

我为此找到了一个很棒的插件: esbuild-plugin-purgecss,由 peteryuan开发,但它不允许传递用于解析需要被解析的 html/views 路径的选项,所以我创建了 esbuild-plugin-purgecss-2 来完成这项工作。 要设置它,请阅读以下内容:

  1. 安装依赖项 npm i -D esbuild-plugin-purgecss-2 glob-all
  2. 将以下代码添加到您的 esbuild.mjs esbuild_watch.mjs 文件中:
// Import Dependencies
import glob from 'glob-all';
import purgecssPlugin2 from 'esbuild-plugin-purgecss-2';

esbuild
    .build({
        plugins: [
            ...
            purgecssPlugin2({
                content: glob.sync([
                    // Customize the following URLs to match your setup
                    './*.html',
                    './views/**/*.html'
                ]),
            }),
        ],
    })
    ...
  1. 现在运行npm run buildnpm run watch将从上面代码中提到的glob.sync([...]中的文件路径中清除purgeCSS。

TL;DR:

  1. 在根目录下创建一个外部配置文件esbuild.mjs,并在scripts: {..}中的package.json中添加运行它的命令,例如"build": "node esbuild.mjs",通过使用npm run build引用和运行配置文件。
  2. ESBuild不支持HMR。此外,您只能使用ESBuild中的watchserve,而不能同时使用两者。为了克服这个问题,可以使用类似Live Server的单独开发服务器库。
  3. 有关完整设置,请参阅我在github上的custom-esbuild-with-scss-purgecss-and-liveserver存储库。

最后的注释:

我知道这是一个很长的帖子,但我花了很多时间才弄清楚这些问题。我的意图是为那些遇到相同问题并试图找出如何入门的人提供帮助。

谢谢。


1
那真是太棒了! :) - Gianluca Romeo
哇,谢谢你详细的回答。这真是省了我很多时间。 - erfling
它还没有过时。ESBuild在html文件的实时重新加载和HMR方面仍然存在问题。我已经在我的github库中创建了一个新的分支,供那些想使用esbuild本地HMR和服务器作为参考的人使用: https://github.com/arslanakram/custom-esbuild-with-scss-purgecss-and-liveserver/tree/esbuild-native - Arslan Akram
1
必须使用 node esbuild.mjs 而不是 node esbuild.js 才能使其正常工作。 - xcvbn
在我的 repopackage.json 文件中,我使用了 "type": "module", 这个选项,这意味着文件扩展名不需要是 .mjs。 - Arslan Akram
显示剩余3条评论

4

除了Arslan的绝妙答案之外,您还可以使用PurgeCSS插件来完全消除第4步。

首先,安装postcss-purgecss包:npm install @fullhuman/postcss-purgecss

然后,将Arslan答案中第2步的代码替换为下面显示的代码(这样就不需要第4步了)。

import esbuild from "esbuild";
import { sassPlugin } from "esbuild-sass-plugin";
import postcss from "postcss";
import autoprefixer from "autoprefixer";
import purgecss from "@fullhuman/postcss-purgecss";

// Generate CSS/JS Builds
esbuild
    .build({
        entryPoints: [
            "yourproject/static/sass/project.scss",
            "yourproject/static/js/project.js",
        ],
        outdir: "dist",
        bundle: true,
        loader: {
            ".png": "dataurl",
            ".woff": "dataurl",
            ".woff2": "dataurl",
            ".eot": "dataurl",
            ".ttf": "dataurl",
            ".svg": "dataurl",
        },
        plugins: [
            sassPlugin({
                async transform(source) {
                    const { css } = await postcss([
                        purgecss({
                            content: ["yourproject/templates/**/*.html"],
                        }),
                        autoprefixer,
                    ]).process(source, {
                        from: "yourproject/static/sass/project.scss",
                    });
                    return css;
                },
            }),
        ],
        minify: true,
        metafile: true,
        sourcemap: true,
    })
    .then(() => console.log("⚡ Build complete! ⚡"))
    .catch(() => process.exit(1));

谢谢分享这个。我还没有测试过,但看起来很不错。 - Arslan Akram

0

在@Arslan Akram的令人印象深刻的回答之后,下面的代码对我也起作用了。只是因为最近的esbuild版本,watch会报错,所以我将其粘贴在这里。

esbuild.mjs

import esbuild from "esbuild";
import { sassPlugin } from "esbuild-sass-plugin";
import postcss from "postcss";
import autoprefixer from "autoprefixer";

const watch = process.argv.includes("--watch");

const args = {
  entryPoints: [
    "src/css/libs.scss",
    "src/css/app.scss",
    "src/js/libs.js",
    "src/js/app.js",
  ],
  outdir: "dist",
  bundle: true,
  metafile: true,
  plugins: [
    sassPlugin({
      async transform(source) {
        const { css } = await postcss([autoprefixer]).process(source, {
          from: undefined,
        });
        return css;
      },
    }),
  ],
};

let ctx;
if (watch) {
  ctx = await esbuild.context(args);
  await ctx.watch();
  console.log("watching...");
} else {
  args.minify = true;
  ctx = await esbuild.build(args);
  console.log("build successful");
}

package.json

{
    "name": "package-name",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "type": "module",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "watch": "node esbuild.mjs --watch",
      "build": "node esbuild.mjs"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
      "esbuild": "0.17.18"
    },
    "devDependencies": {
      "autoprefixer": "^10.4.14",
      "esbuild-sass-plugin": "^2.9.0",
      "postcss": "^8.4.23"
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接