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

kdfy810k  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(222)

背景:

我有一个Webpack setup,我用它来预处理带有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?

  1. ESBuild不支持现成的SCSS。如何配置esbuild-sass-plugin这样的外部插件,甚至更进一步,如何设置PostCSS及其Autoprefixer这样的插件?
    1.如何设置开发服务器与自动重建?
    1.如何设置PurgeCSS?
2izufjch

2izufjch1#

解决方案:

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

1.在根目录中创建新文件:esbuild.js,包含以下内容:

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));

1.在package.json中添加以下代码:

{
    ...
    "scripts": {
        ...
        "build": "node esbuild.js"
    },
...
}

1.通过使用npm run build命令运行构建,这将捆绑您的样式表和脚本,并将它们输出到***dist***目录中。
1.有关更多详细信息和/或添加自定义构建选项,请参阅ESBuild的构建API文档。

2. ESBuild不支持现成的SCSS。如何配置外部插件,如esbuild-sass-plugin,甚至更进一步,如何设置PostCSS和插件,如Autoprefixer?

1.安装npm依赖项:npm i -D esbuild-sass-plugin postcss autoprefixer
1.将您的esbuild.js编辑为以下代码:

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或者运行它的服务器。It doesn't allow both
  2. ESBuild还有另一个限制,it doesn't have HMR support就像Webpack一样。
    1.因此,为了在满足这两个限制的同时仍然允许使用服务器,我们可以使用Live Server。使用npm i -D @compodoc/live-server安装它。
    1.在根目录中创建新文件:esbuild_watch.js,包含以下内容:
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.js",
        "watch": "node esbuild_watch.js"
    },
...
}

1.要运行构建,请使用此命令npm run build
1.运行npm run watch来运行带有自动重建功能的dev服务器。这是一种“hacky”的方式,但是做得很好。

4.如何设置PurgeCSS?

我发现了一个伟大的插件:esbuild-plugin-purgecsspeteryuan创建,但是它不允许为需要解析的html/views路径传递选项,所以我创建了esbuild-plugin-purgecss-2来完成这项工作。要设置它,请阅读下面的内容:
1.安装依赖项npm i -D esbuild-plugin-purgecss-2 glob-all
1.将以下代码添加到esbuild.jsesbuild_watch.js文件中:

// 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([...]中提到的文件路径中清除CSS。

TL;DR:

1.在根目录esbuild.js中创建一个外部配置文件,并在scripts: {..}内的package.json中添加运行该文件的命令,例如"build": "node esbuild.js",以使用npm run build引用和运行配置文件。

  1. ESBuild不支持HMR。此外,您可以使用watchserve与ESBuild,但不能同时使用两者。要克服这一问题,请使用单独的开发服务器库,如Live Server
    1.完整的设置请参考我在github上的custom-esbuild-with-scss-purgecss-and-liveserver仓库。

最终注解:

我知道这是一个很长的线程,但它花了我很多时间来弄清楚这些。我的意图是有这个在这里为其他人寻找同样的问题,并试图找出从哪里开始。

  • 谢谢-谢谢
ax6ht2ek

ax6ht2ek2#

添加到Arslan's terrific answer,您可以使用postcss的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: [
            "roomflows/static/sass/project.scss",
            "roomflows/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: ["roomflows/templates/**/*.html"],
                        }),
                        autoprefixer,
                    ]).process(source, {
                        from: "roomflows/static/sass/project.scss",
                    });
                    return css;
                },
            }),
        ],
        minify: true,
        metafile: true,
        sourcemap: true,
    })
    .then(() => console.log("⚡ Build complete! ⚡"))
    .catch(() => process.exit(1));

相关问题