lucacasonato / esbuild_deno_loader

Deno module resolution for `esbuild`
https://deno.land/x/esbuild_deno_loader
MIT License
160 stars 43 forks source link

added css loader to resolve and load .css files #85

Open scriptmaster opened 1 year ago

scriptmaster commented 1 year ago

deno test -A mod_test.ts:

[native, wasm] bundle config inline import map ... ok (26ms)
[portable, wasm] bundle config inline import map ... ok (7ms)
[native, native] bundle config ref import map ... ok (21ms)
[portable, native] bundle config ref import map ... ok (5ms)
[native, wasm] bundle config ref import map ... ok (25ms)
[portable, wasm] bundle config ref import map ... ok (7ms)
[native, native] custom plugin for scheme ... ok (10ms)
[portable, native] custom plugin for scheme ... ok (4ms)
[native, wasm] custom plugin for scheme ... ok (5ms)
[portable, wasm] custom plugin for scheme ... ok (5ms)
[native, native] custom plugin for scheme with import map ... ok (26ms)
[portable, native] custom plugin for scheme with import map ... ok (5ms)
[native, wasm] custom plugin for scheme with import map ... ok (22ms)
[portable, wasm] custom plugin for scheme with import map ... ok (9ms)
[native, native] uncached data url ... ok (28ms)
[portable, native] uncached data url ... ok (9ms)
[native, wasm] uncached data url ... ok (28ms)
[portable, wasm] uncached data url ... ok (11ms)
[native, native] scss and css ... ok (45ms)
[portable, native] scss and css ... ok (5ms)
[native, wasm] scss and css ... ok (33ms)
[portable, wasm] scss and css ... ok (12ms)

ok | 108 passed | 0 failed (16s)
scriptmaster commented 1 year ago

@lucacasonato please review and merge

bpevs commented 11 months ago

This looks useful, but Deno itself doesn't even support this, does it?

This pr kinda feels outside the scope of this project; the general guidance would probably just be to use a 2nd loader, or a custom_scheme_plugin, rather than merging this into the repo. Or forking / expanding into a more comprehensive Deno-centric build system for client apps.

omar-azmi commented 5 months ago

EDIT: I wrote a Deno compatible package that bundles CSS files (SASS/SCSS not supported). jsr link: https://jsr.io/@oazmi/esbuild-plugin-css deno.land/x link: https://deno.land/x/esbuild_plugin_css npm link: https://www.npmjs.com/package/@oazmi/esbuild-plugin-css

Original comment: for those interested, you can write a simple css plugin to resolve css imports done inside javascript. the code is mostly copied from OP's PR.

// css_plugin.ts
import type * as esbuild from "https://deno.land/x/esbuild@v0.20.1/mod.js"
import { join } from "jsr:@std/path@0.218.2"

export const denoCssPlugin: esbuild.Plugin = {
    name: "deno_css_plugin",
    setup(build) {
        build.onResolve({ filter: /\.css/ }, (args) => {
            return { path: join(args.resolveDir, args.path) }
        })
        build.onLoad({ filter: /\.css/, namespace: "file" }, async (args: esbuild.OnLoadArgs): Promise<esbuild.OnLoadResult> => {
            const contents = await Deno.readTextFile(args.path)
            return { loader: "css", contents }
        })
    }
}

and then to use, simply place this plugin before denoPlugins()

// build.ts
import { denoPlugins } from "jsr:@luca/esbuild-deno-loader@0.9.0"
import { denoCssPlugin } from "./path/to/css_plugin.ts"

const result = await esbuild.build({
    plugins: [denoCssPlugin, ...denoPlugins()],
    /* your configs
    entryPoints: ["./src/mod.ts"],
    outdir: "./dist/",
    ...
    */
})
scriptmaster commented 3 months ago

@bpevs are you aware of the number of devs facing sass and node-sass related install issues, which can be easily remedied with this merge?

Anyway, I have written complete bundler that supports scss/sass/preact/react (vue, svelte and angular on the way) here:

deno install -A -f https://cdn.jsdelivr.net/gh/scriptmaster/sergeant@1.7.1/sergeant.ts

sergeant create react app

bpevs commented 3 months ago

@scriptmaster sass and node-sass related issues are not new to bundlers and loaders: https://github.com/webpack-contrib/sass-loader/issues/205#issuecomment-256716899

That being said, I think handling css files in a loader that is supposed to be for Deno feels improper. To me, handling non-deno related code should be handled in a separate loader. I see the issues around sass, but as mentioned in https://github.com/lucacasonato/esbuild_deno_loader/issues/129, I think the proper solution to this is figuring a better way to ignore/skip css/sass files so that they can be resolved with other loaders. Not to resolve them within deno-loader.

edit: I think something like this is useful. But I just felt like I should explain why this is out of scope of this project / why I don't expect this pr to be merged.

hsn10 commented 2 months ago

Importing CSS import './button.css' is a very common pattern.

It works in stock esbuild. If this doesn't work in deno esbuild version people will simply drop the tool and continue using what they used before.

nandorojo commented 2 months ago

This snippet from @omar-azmi worked for me, thanks!

omar-azmi commented 2 months ago

Glad to hear that it was of use to you @nandorojo . Do note that the snippet won't be able to bundle ccs url imports (i.e. @import url("./some_file_or_url.css")). For a more complete bundling solution, I'd recommend this esbuild plugin library that I wrote: omar-azmi/esbuild-plugin-css . The library handles css url imports, in addition to giving you the option for transforming your bundled css into javascript code that is embeddable in your output javascript file. I was able to bundle microsoft's monaco-editor into a single (humongous) javascript file this way.