evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
37.85k stars 1.12k forks source link

[Questions] support for angular applications #42

Closed ayox closed 4 years ago

ayox commented 4 years ago

esbuild looks promising, I want ask if there is there a support for angular applications, or do you plan to support angular application?

evanw commented 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.

thekip commented 4 years ago

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.

sp90 commented 4 years ago

@thekip do you have any examples on this setup that I could look into?

thekip commented 4 years ago

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.

literalpie commented 3 years ago

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.

gorshkov-leonid commented 3 years ago

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

  1. It takes practically the same time to build this app
  2. I am not sure, but there will be a problem with dynamic chunks when tree-shaking is enabled.
jpike88 commented 3 years ago

"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/

vzakharov-rxnt commented 3 years ago

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.

jpike88 commented 3 years ago

@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.

AnthonyLenglet commented 2 years ago

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:

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

jpike88 commented 2 years ago

@evanw pls reopen this issue

NateRadebaugh commented 2 years ago

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

literalpie commented 2 years ago

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.

kyjus25 commented 2 years ago

Update on this for anyone wondering, it's on the roadmap!

https://angular.io/guide/roadmap#investigate-modern-bundles

fasidOnGit commented 1 year ago

In Angular v15 we have experimental esbuild support in ng build and ng build --watch. https://angular.io/guide/roadmap#investigate-modern-bundles

kyjus25 commented 1 year ago

AnalogJS also has beta support for Vite if anyone would like to consider that as an option as well. Vite, if anyone doesn't know, uses esbuild under the hood