chialab / rna Goto Github PK
View Code? Open in Web Editor NEWπ Build tools for modern web modules and applications.
Home Page: https://chialab.github.io/rna/
License: MIT License
π Build tools for modern web modules and applications.
Home Page: https://chialab.github.io/rna/
License: MIT License
Make build
and serve
command compatible with Encore using esbuild manifest.
this line in my esbuild config... entryNames: '[dir]/[name]',
along with the html plugin... gets me this exception:
β [ERROR] [plugin html] ENOENT: no such file or directory, copyfile 'proj/packages/viewer/dist/assets/index-LCFOZCXA.html' -> 'proj/packages/viewer/dist/[dir]/index.html'
This error came from the "onEnd" callback registered here:
proj/node_modules/esbuild/lib/main.js:814:22:
814 β let promise = setup({
β΅ ^
at setup (file://proj/node_modules/@chialab/esbuild-plugin-html/dist/index.js:60:162521)
at handlePlugins (proj/node_modules/esbuild/lib/main.js:814:23)
at Object.buildOrServe (proj/node_modules/esbuild/lib/main.js:1108:7)
at proj/node_modules/esbuild/lib/main.js:1961:17
at new Promise (<anonymous>)
at Object.build (proj/node_modules/esbuild/lib/main.js:1960:14)
at Object.build (proj/node_modules/esbuild/lib/main.js:1814:51)
at main (proj/scripts/build-app.js:147:32)
Error: Build failed with 1 error:
error: ENOENT: no such file or directory, copyfile 'proj/packages/viewer/dist/assets/index-LCFOZCXA.html' -> 'proj/packages/viewer/dist/[dir]/index.html'
at failureErrorWithLog (proj/node_modules/esbuild/lib/main.js:1557:15)
at proj/node_modules/esbuild/lib/main.js:1215:28
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
errors: [
{
pluginName: 'html',
text: "ENOENT: no such file or directory, copyfile 'proj/packages/viewer/dist/assets/index-LCFOZCXA.html' -> 'proj/packages/viewer/dist/[dir]/index.html'",
location: null,
notes: [Array],
detail: [Error]
}
],
warnings: []
}
clearly the [dir]/
bit isn't being resolved.
interestingly, [dir]/
in `assetNames works fine, though... it does lead to some weird directory structures.. :)
I'm trying to use esbuild-plugin-html with the esbuild-plugin-glob plugin to use it with several html files, like this:
[ "pages/**/*.html", "dynamic_pages/**/*.html"];
This breaks as the code now just uses the filename and not the directory. I hacked it to work by changing the creation of the finalOutputFile const in the index.js around line 28595 to this:
const finalOutputFile = `${workingDir}/${outDir}/${inputs[0]}`;
I'm not making a PR as I have a hard time understanding the original way of setting the path and what else in the code it affects but maybe you can have a look and adjust it so it does take the path into account?
Tracking evanw/esbuild#475
Hi there, thanks for the great plugins, they help me a lot.
Although the types are published in the npm registry, it is ignored in the source code. Could you please add it here too? Thanks!
Line 4 in 5e26622
So my previous webpack config would generate something which looked like this. html-webpack-plugin
public
βββ index.html
βββ ui-assets
βββ assets-manifest.json
βββ main.d2fe0910b8.js
βββ main.d2fe0910b8.js.map
βββ vendor.67dfc8f6a1.js
βββ vendor.67dfc8f6a1.js.map
This was useful to us because we didn't want the main entry point (index.html) to be hashed. it also allowed us to serve static assets from a different place.
@chialab/[email protected]
generates this:
public
βββ 1-25MTWOSN.js
βββ 1-25MTWOSN.js.map
βββ 1-LCOOVKTY.css
βββ 1-LCOOVKTY.css.map
βββ index-LJMJ3LED.html
We don't want the main entry point hashed, and we would like the assets (JS and css files) to be in a separate directory.
Is this possible for you to implement?
In es-plugin-env, if an environment variable contains symbols, CommonProgramFiles(x86)
for example, esbuild throws an error.
error: The define key "process.env.CommonProgramFiles(x86)" contains invalid identifier "CommonProgramFiles(x86)"
Error: Build failed with 2 errors:
error: The define key "process.env.CommonProgramFiles(x86)" contains invalid identifier "CommonProgramFiles(x86)"
error: Cannot read properties of undefined (reading 'errors')
at failureErrorWithLog (D:\Code\Test\esbuild test\node_modules\esbuild\lib\main.js:1494:15)
at D:\Code\Test\esbuild test\node_modules\esbuild\lib\main.js:1151:28
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
errors: [
{
detail: undefined,
location: null,
notes: [],
pluginName: '',
text: 'The define key "process.env.CommonProgramFiles(x86)" contains invalid identifier "CommonProgramFiles(x86)"'
}
]
I believe this is the root of the issue:
rna/packages/esbuild-plugin-env/lib/index.js
Lines 5 to 19 in 5a1edb5
The acorn parser does not extrapolate comments in the code, so we are not able to detect magic imports from the AST. Provide an API to collect comments across plugins.
For example, I'm using esbuild-plugin-import-glob, but its onLoad
hook prevents esbuild-rna
plugins from running their transform hooks.
How do I make them work together?
Is the setupPlugin
method a possible solution?
Add node engines constraints to package.json files with the minimum required node version with esm support.
Add the option to run babel for es5 target.
Hey, great plugin.
There's just one issue for us, currently the exported folders are hardcoded to iife
or esm
.
We need our assets folder to have a specific name, is it possible to offer an override for this?
So instead of dist/iife/index.js
we can have dist/assets/index.js
(plus same in the index.html also)
Each change in watch mode concatenates the previous tests
Github repo:
https://github.com/oscarmarina/test-report
Stackblitz:
https://stackblitz.com/github/oscarmarina/test-report?file=README.md
git clone https://github.com/oscarmarina/test-report
cd test-report
npm i
npm run test:watch
Web Dev Server lacks of native support for CSS hmr.
Add methods and commands documentation to the readme.
Perhaps I'm overlooking an existing option? My expectation is that this would just be copied over to the assets build folder, just like any other asset.
src/client/styles/main.css:8:11: error: No loader is configured for ".ttf" files: src/client/fonts/VT323.ttf
8 β src: url('../fonts/VT323.ttf') format('truetype');
Integrate the saucelabs launcher for the test runner.
Support HTML entry point using the HTMLBundler of the old rna-cli.
I have a component requiring an image that is processed via ESBuild's file loader.
cf. https://github.com/martpie/museeks/blob/b7e644ac1bf8bf383cbbde6fa6b2f32326673aac/esbuild.mjs#L87-L92
It would seem those assets are then placed in the JS build directory instead of the root of the dist folder:
but ESBuild translates the URL to ./placeholder.png
, which is of course not resolvable from app.html
(at the root) and triggers a 404.
Sidenote: maybe even CSS should be at the root.
Currently it's not possible for me to use my dev script for esbuild with this as each time a change is made I'll need to open up a new page since the hash changed. An option to omit the hash would solve this.
Use case:
I am trying to build multiple HTML files such that all entries are populated with the same directory structure as my source folder.
Attempt:
I used the following build configuration in my esbuild.config.js
file:
import esbuild from "esbuild";
import htmlPlugin from "@chialab/esbuild-plugin-html";
await esbuild.build({
entryPoints: ["src/index.html","src/sub/index.html"],
entryNames: '[dir]/[name]',
outdir: "public",
outbase: "src",
plugins: [htmlPlugin()],
assetNames: "[dir]/[name]",
bundle: true,
minify: true,
write: true,
});
Expected result:
Assets are loaded into an "assets" folder, and the HTML file directories are preserved in the out folder.
Further, I would expect sub/sub.html
's css file to resolve to ../css/whatever.css
rather than css/whatever.css
. The latter occurs, resulting in a 404 response for the css fetch.
Observed result:
css
folder.https://github.com/chialab/rna/blob/main/packages/wtr-mocha-reporter/lib/reportBrowserLogs.js
import { colors } from '@chialab/rna-logger';
@chialab/rna-logger
The problem is with the esbuild-html-plugin.
I have a script defined in my HTML entry point like this:
The means that it gets transformed to something like:
<script src="index-234234.js></script>If I use my app as a SPA, this script path is appended to the app's URL, like:
https://example.com/some/path/index-23434.js
whereas it should be in the root folder: https://example.com/index-23434.js
Currently the only way out is to use a proxy, which I don't want to.
The plugin should allow setting paths to assets like this:
<script src="/index.js></script> (with the forward slash, indicating that whatever name it eventually gets, it's always available from the root)Currently the plugin just ignores such assets.
See: evanw/esbuild#1211
Here's my folder structure:
package.json
{
"name": "esbuild-html",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"type": "module",
"devDependencies": {
"@chialab/esbuild-plugin-html": "^0.11.19",
"esbuild": "^0.12.20"
}
}
src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Home</title>
</head>
<body>
<h1>Home</h1>
<script src="index.js" type="module"></script>
</body>
</html>
src/index.js
console.log('Home')
export {}
src/sub/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Sub</title>
</head>
<body>
<h1>Sub</h1>
<script src="index.js" type="module"></script>
</body>
</html>
src/sub/index.js
console.log('Sub')
export {}
build.js
import esbuild from 'esbuild'
import htmlPlugin from '@chialab/esbuild-plugin-html'
esbuild.build({
entryPoints: ['./src/index.html', './src/sub/index.html'],
outdir: './dist/',
plugins: [htmlPlugin({})]
})
When I run node build.js
I expect the resulting dist
directory to look something like this:
dist/
ββ index.html
ββ index.js
ββ sub/
ββ index.html
ββ index.js
What I get instead is:
dist/
ββ index-[hash1].html
ββ index-[hash2].html
ββ index.js (Contents are `module.exports = './index-[hash1].html'`
ββ sub/
β ββ index.js (Contents are `module.exports = '../index-[hash2].html'`
ββ esm/
ββ index.js (Contents are the top level index.js, the sub/index.js contents are just gone, probably overridden)
I'm okay with the hashes (as long as it's consistent), but it looks like it's not doing things relative to the outdir per the "lowest common ancestor" rule outlined in the esbuild documentation. And them it seems to be just completely overriding some files.
Admittedly, I'm pretty new to esbuild. I could me misconfiguring things. Would love some direction if I'm missing something.
I was trying to convert react to ESM so that browser can consume it as a native ESM module.
Tested with [email protected]
Here is esbuild setup:
import { build } from "esbuild";
import commonjsPlugin from "@chialab/esbuild-plugin-commonjs";
await build({
entryPoints: [
"./node_modules/react/index.js",
],
bundle: true,
outfile: "out.js",
format: "esm",
loader: {
".js": "js",
},
plugins: [commonjsPlugin()],
})
The output is still commonjs module style while I was expecting module.exports
to be converted to ESM export
statements
When esbuild runs in serve mode it builds and references the main index.html in memory.
this means the relative files it refers to donβt work properly.
here is an example of an error:
β [ERROR] [plugin html] Build failed with 1 error:
src/2.js:1:7: ERROR: Could not resolve "./ui-assets/1-7YBC7F6V.js"
This error came from the "onLoad" callback registered here:
../node_modules/esbuild/lib/main.js:845:22:
845 β let promise = setup({
β΅ ^
at onTransform (file:///../node_modules/@chialab/esbuild-rna/lib/index.js:469:20)
at setup (file:///../node_modules/@chialab/esbuild-plugin-html/dist/index.js:61:162844)
at handlePlugins (/../node_modules/esbuild/lib/main.js:845:23)
at Object.buildOrServe (/../node_modules/esbuild/lib/main.js:1139:7)
at /../node_modules/esbuild/lib/main.js:2080:17
at new Promise (<anonymous>)
at Object.build (/../node_modules/esbuild/lib/main.js:2079:14)
at Object.build (/../node_modules/esbuild/lib/main.js:1929:51)
at file:///../cms/build.mjs:97:9
Error: Build failed with 1 error:
error: Build failed with 1 error:
src/2.js:1:7: ERROR: Could not resolve "./ui-assets/1-7YBC7F6V.js"
at failureErrorWithLog (/../node_modules/esbuild/lib/main.js:1605:15)
at /../node_modules/esbuild/lib/main.js:1251:28
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
errors: [
{
detail: [Error],
location: null,
notes: [Array],
pluginName: 'html',
text: 'Build failed with 1 error:\n' +
'src/2.js:1:7: ERROR: Could not resolve "./ui-assets/1-7YBC7F6V.js"'
}
],
warnings: []
}
one solution Iβve seen is to accept a new option serve
, which will use data URLs for assets instead of generating files.
This may be a workaround until esbuild provides better support.
More info:
I have a problem when using the esbuild-plugin-html
(0.15.9) with esbuild
option sourcemap
enabled.
This results in as html file that references the .js.map
file instead of the desired .js
file.
Excerpt of esbuild.config.js
file:
import esbuild from 'esbuild';
import htmlPlugin from '@chialab/esbuild-plugin-html';
esbuild.build({
entryPoints: [ './index.html' ],
plugins: [ htmlPlugin() ],
bundle: true,
sourcemap: true,
});
Content of the index.html
file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="./index.ts"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
Excerpt of output index.html
file:
<script src="1.js.map" type="application/javascript"></script>
Desired output:
<script src="1.js" type="application/javascript"></script>
Possible fix in file esbuild-plugin-html/lib/collectScripts.js
const jsOutput = files.find((file) => file.endsWith('.js'));
const cssOutputs = files.filter((file) => file.endsWith('.css'));
I am writing an application in Electron and I need to set externals to some names of Node.js native modules.
Is there any reason why externals is set to []
here?
rna/packages/esbuild-plugin-html/lib/index.js
Line 203 in 3544f2c
Is it something we could override via an option?
Under windows, my html source code is this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo</title>
<link href="./app.less" rel="stylesheet">
<script type="module" src="./app.ts"></script>
</head>
<body>
</body>
</html>
I run esbuild by code, the config is :
{
//...
assetNames: 'assets/[name]',
chunkNames: 'assets/[name]',
//...
}
the resulting html is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo</title>
<link href="assets\app.css" rel="stylesheet">
<script src="assets\app.js" type="module"></script>
</head>
<body>
</body>
</html>
As you can see, the link & scripts sources contains a \
instead of /
Quick question, I'd like to use @chialab/esbuild-plugin-worker
together with gulp-esbuild
as a plugin for loading workers, but I am not clear on how I'm supposed to do that. the docs don't mention how you create workers.
Hi guys,
I am currently trying the html plugi. It looks promising but currently I am facing 2 issues:
/
, it looks in my own /
dir. It would be fine if we could have a root dir in options, or maybe even root dirshttp://
looking in my own dir tooI recently started a project which tries to implement a map renderer in Rust. I'm currently evaluating which bundler is the best for the task as I require two features:
import.meta.url
in CJS and ESM modules, especially for .wasm files.I tried the plugin @chialab/esbuild-plugin-meta-url
to solve the second goal, but esbuild is not copying assets to the output directory.
Config:
build.mjs
import esbuild from 'esbuild';
import metaUrlPlugin from '@chialab/esbuild-plugin-meta-url';
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
format: "esm",
platform: "browser",
outdir: "dist/esbuild/",
plugins: [
metaUrlPlugin(),
],
});
Is there more configuration needed?
Right now, the RNA ecosystem of esbuild plugins has a lot of interdependencies. Some plugin explicitly depends on other, so we need to ensure that all the plugin chain is respected when a plugin is setting up.
See: swc-project/swc#1617
Add support for e2e testing with the puppeteer launcher.
I'm trying to use esbuild-plugin-meta-url, but its onLoad
hook is only being called for dependencies. Do I need a special onResolve
hook to enable processing of local modules too?
I should note that I'm using esbuild.build
API with bundle: true
.
The hash only depends on the import statements, not on the contents of the file.
It's not possible to use this for browser caching since editing the imported scripts doesn't update the output hash.
See here for an example: (the same issue is present for CSS)
rna/packages/esbuild-plugin-html/lib/collectScripts.js
Lines 22 to 35 in 7d9fd9e
I'm wondering if you could instead specify the entryNames
and let esbuild
calculate the hash.
I don't think the finisher has to do anything different, since it already gets the entrypoint by position and not file name.
Tracking modernweb-dev/web#1387
Add support for jsx auto runtime, pragma import and template strings transpiling.
For the CSS assets generated by esbuild (included in the metafile, not as a ), the generated file path appears platform specific. When run on Windows, the path is a single backslash, which is not the standard (forward slash).
In the worst case, a path given to the "loadStyle" function is e.g. "static\index-23423.css", in which the single backslash actually produces a completely wrong path, preventing CSS from rendering in the browser.
Please always use forward slashes as path separators in the generated HTML.
By the way, why are CSS assets from the metafile included es loader scripts instead of a simple <link ...>?
The problem is in https://github.com/chialab/rna/blob/main/packages/esbuild-plugin-html/lib/collectScripts.js
Lines 110-111.
Plugins like esbuild-plugin-html
and rna-storybook
create files in the output dir in a separated process (eg, directly using the fs). We need to provide a better way to reconcile output manifests and watched files.
Right now, The RNA dev server pre-bundles node_modules dependencies on request. We should watch dependency files anyway and then invalidate the bundle.
I've been trying to produce a valid React build first with esbuild and then with rna, without much success.
"react": "^17.0.2",
"react-dom": "^17.0.2",
The furthest I got is this esbuild command:
esbuild src/index.jsx --bundle --outdir=esbuild/ --loader:.js=jsx --minify --chunk-names=chunks/[name]-[hash] --entry-names=[dir]/[name]-[hash]
It generates two files, js and css, content hashed.
Next step would be including this in html, which is where my struggle began. I tried your HTML plugin for esbuild, but it did not generate correct JS output, only small files a few dozen bytes in size.
Now with RNA CLI:
"build": "yarn rna build src/index.html --output rna",
"devDependencies": {
"@chialab/rna": "^0.15.3",
"@chialab/rna-bundler": "^0.15.16"
}
It produced the following JS, a bunch of PNGs, index.html and manifest.json, none of the files are content hashed.
And linked js.map from HTML where JS was linked (what?!). Also no content hash for assets, so can't work in production.
Do you have an example of building a standard React application built with react-scripts?
"build": "react-scripts build",
esbuild and the ecosystem around it seems to have a steep learning curve, and figuring it out with google, Stack Overflow or
official docs is not an option. All online tutorials I found, in text or video format, do not have content hashing for assets, they just copy the HTML as is.
When using the HTML plugin and I import styles in JS via
import "path/to/style.css";
it results in an additional script tag added to the HTML:
<script type="module">
(function() {
function loadStyle(url) {
var l = document.createElement('link');
l.rel = 'stylesheet';
l.href = url;
document.head.appendChild(l);
}
loadStyle('style.css');
}());
</script>
Not sure what the reason for this is over just including it via a <link>
tag directly, perhaps to avoid render blocking?
Anyway I would like to have at least an option to configure it s.t. this would just add
<link rel="stylesheet" href="style.css"/>
because I want my styles to be render blocking (to avoid FOUC) and save some bytes.
The code responsible for this seems to be in collectScripts.js.
Happy to provide the PR for this change myself if you agree with this proposal.
Thanks for this plugin btw :)
Currently we use postCSS to resolve url references for both bundler and server. We could use the builtin esbuild resolve hook instead, in order to completely avoid postcss parsing when not required.
Using a project directory as root of the Web Dev Server breaks support for node_modules resolution.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.