Closed ayox closed 4 years ago
I'm not familiar with Angular but it looks like Angular has a custom compiler that is pretty different than other JavaScript build tools. So I don't think Angular applications will work with esbuild.
I'm only intending for esbuild to target a certain sweet spot of use cases (bundling JavaScript, TypeScript, and maybe CSS). I don't think Angular is mainstream enough to warrant building into the core of esbuild, and since esbuild doesn't have plugins it won't be possible to add Angular support to esbuild.
Actually with some manual working it's possible to build Angular with tools such as es-build. Angular has a standlone compiler which can be used to compile angular components to regular typescript files and than you can hook it up with esbuild.
Despite the fact this is possible it's going to be a really hard way, because angular teams doesn't care too much about cases where angular apps built with tooling outside of angular's ecosystem.
@thekip do you have any examples on this setup that I could look into?
The main idea is to run angular compiler on your angular project to compile all html/ts files into regular js:
ngc --build ./tsconfig.app.json --outDir ./ngc
ngc
stands for angular compiler and it is a drop-off replacement for tsc
command (Typescript Compiler)
And then run any of building tool which can work with ES files, such as esbuild.
You will probably have a problems with scss files if you use them because ngcc compiler understand only pure css. The output still will not be the same to what AngularCLI is produce, because they have few additional steps in pipeline (BuildOptimizer, conditional loading bundles es5/es2015, service workers, index.html production and etc)
PS. Angular compiler is implented as set of custom typescript transformers using public typescript api. So you can try too hook up this transformers into other tools which use typescript natively. But there are no documentation about angular compiler internals and only on way to find some detail of implementation is digging into angular CLI code.
To build on @thekip's comment, I got pretty far just by doing:
"ngcc": "ngcc",
"esbuild": "ngc build -p tsconfig.app.json && esbuild ./out-tsc/app/main --bundle --minify --splitting --outdir=out --format=esm",
then running npm run ngcc
once and npm run esbuild
to build the project. I then had to manually copy the index.html
file to the folder where the main.js file was output, and add <script src="main.js" defer></script>
to the index.html
This feels pretty close, but I'm getting the error:
Error: Angular JIT compilation failed: '@angular/compiler' not loaded! - JIT compilation is discouraged for production use...
I'm probably not going to look into this much more because it still requires running ngc
so the speed improvements will probably be very minor. I'm just putting this here in case it helps others.
Hi, here is a working experiment for a simple app
package.json "@angular-builders/custom-webpack": "~11.1.1" "esbuild-loader": "~2.11.0"
angular.json projects.architect.serve.builder "@angular-builders/custom-webpack:dev-server" projects.architect.build.builder "@angular-builders/custom-webpack:browser" with options
"options": {
"customWebpackConfig": {
"path": "./custom-webpack.conf.js",
"replaceDuplicatePlugins": true
},
...
}
custom-webpack.conf.js
const ESBuildPlugin = require("esbuild-loader/dist/plugin").default;
module.exports = function (config, opts, {target, configuration}) {
config.module = {
...config.module,
rules: [
...config.module.rules.filter(rule => !rule || !rule.use || !rule.use.loader || !rule.use.loader.includes("/babel-loader/")),
{
test: /\.ts$/,
loader: "esbuild-loader",
options: {
loader: "ts",
target: "es2018"
}
},
{
test: /\.js$/,
loader: "esbuild-loader",
options: {
target: "es2018"
}
}
]
}
var opts = undefined;
if (target === "serve") {
opts = {
options: {
minify: false
}
}
config.mode = "development";
config.devtool = "none";
}
else {
config.mode = "production";
}
config.plugins = [
...config.plugins,
new ESBuildPlugin(opts)
]
return config
}
It seems that
"I don't think Angular is mainstream enough"
I fail to see how you don't consider Angular to be squarely in the 'mainstream' category of frameworks, and by some perspectives even consider it the most prominent. Esbuild will ultimately follow the path you want it to, but it's a pretty sizeable shortcoming if no accommodations are made for angular. Even exposing an esbuild go API would at least allow other bundlers to extend it without a loss in performance.
More reading: https://www.codeinwp.com/blog/angular-vs-vue-vs-react/
I agree, there is lots of Angular in enterprise. Enterprise has virtually unlimited money, especially when it comes to tooling. You might get sponsored/promoted by those big companies who need it.
@evanw to @vzakharov-rxnt’s point, it would be extra attractive to the likes of Google as it would support their framework and be written in their language.
I've done a bit of digging on my end regarding using esbuild
best I could get was this
"build:esbuild": "ngc build -p tsconfig.app.json --target es5 && esbuild out-tsc/app/main --outdir=esbuild-dist --splitting --bundle --minify --format=esm",
this does create a "esbuild-dist" folder with everything properly split into chunks, the only thing left to do is:
assets
folder, the favicon and the index.html
file into the build folderindex.html
file to add <script src="main.js" defer></script>
at the end of the body
when launching a server on this folder however, ivy seems to get in the way, with a missing 'ɵmod' property
error, I've looked at the non-minified build code and it does look like ɵmod
, ɵcmp
and other ivy related additions are missing
Looking into the angular-cli source code it looks like this part might be handled by a webpack plugin, so looks like that's the brick wall with this idea sadly, unless someone would be willing to pick up the task of create a esbuild version of the plugin
@evanw pls reopen this issue
Looks like angular cli is starting to use esbuild internally. See changes related to @angular-devkit/build-angular
https://github.com/angular/angular-cli/blob/master/CHANGELOG.md
To add some more details,
My conclusion is that the lack of Angular support for esbuild is the responsibility of the Angular team, not esbuild. Angular has a pipeline that depends heavily on TypeScript tooling, and until they break that apart, there is nothing esbuild can reasonably do to better support Angular.
Update on this for anyone wondering, it's on the roadmap!
In Angular v15 we have experimental esbuild support in ng build
and ng build --watch
.
https://angular.io/guide/roadmap#investigate-modern-bundles
esbuild
looks promising, I want ask if there is there a support for angular applications, or do you plan to support angular application?