profile
viewpoint

evanw/esbuild 9085

An extremely fast JavaScript bundler and minifier

evanw/csg.js 1382

Constructive solid geometry on meshes using BSP trees in JavaScript

evanw/fsm 154

Finite State Machine Designer

evanw/float-toy 69

Use this to build intuition for the IEEE floating-point format

evanw/buddy-malloc 47

An implementation of buddy memory allocation

evanw/esprima-cpp 40

JavaScript parser in C++ (port of Esprima)

evanw/bitscript 29

An experimental language that compiles to JavaScript and C++

evanw/cs224final 29

Final project for CS 224: Interactive Computer Graphics

evanw/emscripten-library-generator 24

A library generator for the emscripten compiler

fork evanw/tree-shaking-example

Tree-shaking of Rambda, Ramda and Lodash with Webpack, Parcel and Rollup

fork in 3 days

startedmischnic/tree-shaking-example

started time in 3 days

issue closedevanw/esbuild

How to support decorator syntax

How to support decorator syntax

closed time in 3 days

fangkyi03

issue commentevanw/esbuild

How to support decorator syntax

Closing as a duplicate of #104.

fangkyi03

comment created time in 3 days

issue closedevanw/esbuild

[Feature] Support references to non-js assets

Even if not supporting the likes of CSS transforms (sass/less), it would be nice if you added support for referencing static assets like images, etc. Can simply hold a reference, and output to the dist directory with originalname.hash.ext ... and then put the output path into the JS... that output path should probably be configurable as well... such as / (default), or /assets via configuration, etc.

This is what a lot of bundlers are doing for most things. Inlining and (s)css support would probably be natural followup support.

closed time in 3 days

tracker1

push eventevanw/esbuild

Evan Wallace

commit sha a2392b8664219896cd8e3bd07ce9f7a93353e798

fix issues with the file loader (fixes #14)

view details

push time in 3 days

push eventevanw/esbuild

Ade Viankakrisna Fadlil

commit sha 12ff76f22f156f6161adeb4a8241d4b4d37a8f4b

add file loader (#135)

view details

push time in 4 days

PR merged evanw/esbuild

add file loader
+123 -32

0 comment

8 changed files

viankakrisna

pr closed time in 4 days

Pull request review commentevanw/esbuild

add file loader

 package bundler  import (+	"fmt" 	"path"+	"strings" 	"testing"  	"github.com/evanw/esbuild/internal/fs" 	"github.com/evanw/esbuild/internal/logging" 	"github.com/evanw/esbuild/internal/parser" 	"github.com/evanw/esbuild/internal/printer" 	"github.com/evanw/esbuild/internal/resolver"+	"github.com/kylelemons/godebug/diff" )  func assertEqual(t *testing.T, a interface{}, b interface{}) { 	if a != b {-		t.Fatalf("%s != %s", a, b)+		stringA := fmt.Sprintf("%v", a)+		stringB := fmt.Sprintf("%v", b)+		if strings.Contains(stringA, "\n") {+			t.Fatal(diff.Diff(stringA, stringB))

I understand why you did this, but this is going to make it harder to update tests since I've been copying and pasting the output of the tests to accept the new output, and this interleaves the old and new output. Luckily it's easy to disable by just commenting out a few lines, so I don't think it's a big problem.

Really I should figure out some system of doing snapshot-style testing so that test output can be updated automatically...

viankakrisna

comment created time in 4 days

Pull request review commentevanw/esbuild

add file loader

 func run(fs fs.FS, args argsObject) { 		} 		args.logInfo(fmt.Sprintf("Wrote to %s (%s)", path, toSize(len(item.JsContents)))) +		// Write out the additional files+		for _, file := range item.AdditionalFiles {

The contents of AdditionalFiles end up being written out twice because they are both written out here and duplicated to become normal files in this code elsewhere:

		for _, bundle := range group {
			for _, additionalFile := range bundle.AdditionalFiles {
				if additionalFile.Path != "" {
					results = append(results, BundleResult{additionalFile.Path, []byte(additionalFile.Contents), "", []byte(""), []AdditionalFile{}})
				}
			}
		}

That's ok, I can fix it after landing this.

viankakrisna

comment created time in 4 days

push eventevanw/esbuild

Evan Wallace

commit sha 57b68b66bd095c61ef13e9ab7a0b666dba53d3d8

fixes for resolve-extensions

view details

push time in 4 days

push eventevanw/esbuild

Ade Viankakrisna Fadlil

commit sha addc173289162a0f59ae05afe921e0e7c3c21c30

add resolve-extension-order (#142)

view details

push time in 4 days

pull request commentevanw/esbuild

add resolve-extension-order

Good to know about the precedent from Webpack. In that case --resolve-extensions sounds fine to me.

viankakrisna

comment created time in 4 days

push eventevanw/esbuild

Evan Wallace

commit sha 0e0a9fbde87faaa1f72e14ff54ab7d54f614eb56

fixes for tsconfig.json "paths" support (fixes #60)

view details

push time in 4 days

issue closedevanw/esbuild

Support tsconfig paths in order to avoid 'could not resolve`

tsconfig

{
  "compilerOptions": {
    ...baseConfig,
    "paths": {
      "@oss-stealth/unikernel/*": ["./src/unikernel/*"],
      "@oss-stealth/rpc/*": ["./src/rpc/*"],
      "@oss-stealth/runtime/*": ["./src/runtime/*"],
      "@oss-stealth/ui/*": ["./src/ui/*"],
      "@oss-stealth/typescript/*": ["./src/typescript/*"],
      "@oss-stealth/fs/*": ["./src/fs/*"],
      "@oss-stealth/ts/*": ["./src/ts/*"],
      "@oss-stealth/leela/*": ["./src/leela/*"],
      "@oss-stealth/satya/*": ["./src/satya/*"],
      "@oss-stealth/microkernel/*": ["./src/microkernel/*"]
    }
  }
}

error

src/hub/src/pages/repo/components/repo_host.tsx:6:43: error: Could not resolve "@oss-stealth/rpc/src/index"
import { RPC, FrameHostRPCTransport } from "@oss-stealth/rpc/src/index";

closed time in 4 days

abhishiv

push eventevanw/esbuild

Ade Viankakrisna Fadlil

commit sha a982800aa263867a0fcd45a0be29c97448da37a3

add tsconfig.json compilerOptions.paths support (#144)

view details

push time in 4 days

Pull request review commentevanw/esbuild

add tsconfig.json compilerOptions.paths support

 func (r *resolver) loadAsFileOrDirectory(path string) (string, bool) { 	return "", false } +func isTsConfigPathMatch(pattern string, path string) (string, bool) {+	starIndex := strings.IndexRune(pattern, '*')+	if starIndex == -1 {+		firstPath := strings.Split(path, "/")[0]+		return strings.Replace(path, pattern+"/", "", 1), firstPath == pattern+	}++	elements := strings.Split(pattern, "*")+	if starIndex == 0 {+		suffix := elements[1]+		return strings.Replace(path, suffix, "", 1), strings.HasSuffix(path, suffix)+	}+	prefix := elements[0]+	return strings.Replace(path, prefix, "", 1), strings.HasPrefix(path, prefix)+}+ func (r *resolver) loadNodeModules(path string, dirInfo *dirInfo) (string, bool) { 	for { 		// Handle TypeScript base URLs for TypeScript code-		if dirInfo.tsConfigJson != nil && dirInfo.tsConfigJson.absPathBaseUrl != nil {-			basePath := r.fs.Join(*dirInfo.tsConfigJson.absPathBaseUrl, path)-			if absolute, ok := r.loadAsFileOrDirectory(basePath); ok {-				return absolute, true+		if dirInfo.tsConfigJson != nil {++			if dirInfo.tsConfigJson.absPathBaseUrl != nil {+				if dirInfo.tsConfigJson.paths != nil {+					for key, originalPaths := range dirInfo.tsConfigJson.paths {+						for _, originalPath := range originalPaths {

This doesn't follow the behavior of the TypeScript compiler which prefers exact matches over pattern matches and prefers matches with longer prefixes over matches with shorter prefixes. That's ok though, I'll fix it.

viankakrisna

comment created time in 4 days

Pull request review commentevanw/esbuild

add tsconfig.json compilerOptions.paths support

 console.log(main_esm_default()); 	}) } +func TestTsConfigPaths(t *testing.T) {+	expectBundled(t, bundled{+		files: map[string]string{+			"/Users/user/project/src/entry.js": `+				import fn from 'core/test'+				import fn2 from 'testing/test'

It appears this case isn't actually supposed to work. At least the TypeScript compiler throws an error here. I can do the testing work and make adjustments to the algorithm as appropriate.

viankakrisna

comment created time in 4 days

issue commentevanw/esbuild

transform() API - "name" option

The option is called sourcefile, not filename:

https://github.com/evanw/esbuild/blob/6a6ee4ea7b6c83d0f3f5b94fdffe575845b3c244/npm/esbuild/lib/main.d.ts#L9

I should probably make the API throw an error when you use transform() with sourcemap but not sourcefile. But that's a breaking change so I think I'll wait on that until the next round of breaking changes.

FredKSchott

comment created time in 4 days

created tagevanw/esbuild

tagv0.4.3

An extremely fast JavaScript bundler and minifier

created time in 4 days

push eventevanw/esbuild

Evan Wallace

commit sha 6a6ee4ea7b6c83d0f3f5b94fdffe575845b3c244

publish 0.4.3 to npm

view details

push time in 4 days

push eventevanw/esbuild

Evan Wallace

commit sha 3dd0143592264300c7f0f5cc1e30a7cbeac4ed26

fix #156: preserve optional chain parentheses

view details

push time in 4 days

issue closedevanw/esbuild

optional chaining grouping bug

An obscure corner of the spec as gleaned from https://github.com/estree/estree/pull/204 ...

Given:

$ esbuild --version
0.4.2
$ cat optchain.js
let o=null;try{o=(o?.a).b||"FAIL";}catch(x){}console.log(o||"PASS");

Expected:

$ cat optchain.js | node-v14.3.0
PASS

Actual:

$ cat optchain.js | esbuild --minify | node-v14.3.0
FAIL
$ cat optchain.js | esbuild --minify
let o=null;try{o=o?.a.b||"FAIL"}catch(a){}console.log(o||"PASS");

Down-levelling will preserve the intent of the original parentheses however:

$ cat optchain.js | esbuild --target=es2019 --minify | node-v14.3.0
PASS
$ cat optchain.js | esbuild --target=es2019 --minify
let o=null;try{o=(o==null?void 0:o.a).b||"FAIL"}catch(a){}console.log(o||"PASS");

closed time in 4 days

kzc

issue commentevanw/esbuild

optional chaining grouping bug

Ah crap. Thanks so much for calling this out. I made sure the lowering worked in that case but forgot about pass-through. I like the idea in that thread of thinking of ?. as a normal infix operator, as well as . belonging to an optional chain. I'll figure out how to fix this.

kzc

comment created time in 4 days

push eventevanw/esbuild

AnnatarHe

commit sha 9863668f2fed389620c4e778ec0ccea5d15ddf50

fix(doc): remove duplicated `because` (#155)

view details

push time in 5 days

PR merged evanw/esbuild

fix(doc): remove duplicated `because`
+1 -1

0 comment

1 changed file

AnnatarHe

pr closed time in 5 days

issue commentevanw/esbuild

esbuild-wasm support for JS API

The test doesn't evaluate the bundled code. If you change it to evaluate the code, the Rollup build will crash:

diff --git a/src/react-icons.js b/src/react-icons.js
index dce9578..1da9aee 100644
--- a/src/react-icons.js
+++ b/src/react-icons.js
@@ -1,3 +1,3 @@
 import { FaBeer } from 'react-icons/fa';

-console.log(FaBeer);
\ No newline at end of file
+console.log(FaBeer());
\ No newline at end of file

Results with patch:

$ node esbuild/react-icons.js
{
  '$$typeof': Symbol(react.element),
  type: [Function: IconBase],
  key: null,
  ref: null,
  props: { attr: { viewBox: '0 0 448 512' }, children: [ [Object] ] },
  _owner: null
}
$ node rollup/react-icons.js
rollup/react-icons.js:1

TypeError: (void 0) is not a function
    at rollup/react-icons.js:1:8276
    at Array.map (<anonymous>)
    at e (rollup/react-icons.js:1:8244)
    at rollup/react-icons.js:1:8315
    at FaBeer (rollup/react-icons.js:1:9443)
    at Object.<anonymous> (rollup/react-icons.js:1:9483)
    at Module._compile (internal/modules/cjs/loader.js:1156:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)
    at Module.load (internal/modules/cjs/loader.js:1000:32)
    at Function.Module._load (internal/modules/cjs/loader.js:899:14)
kzc

comment created time in 5 days

issue commentevanw/esbuild

esbuild-wasm support for JS API

Just ran the benchmark on version 0.3.9 vs. 0.4.2:

file                           size
-------------------------  --------
esbuild@0.3.9/lodash-es     289.3kb
esbuild@0.4.2/lodash-es     285.4kb
webpack/lodash-es            20.5kb
parcel/lodash-es             18.6kb
rollup/lodash-es             18.2kb

esbuild@0.3.9/lodash        225.3kb
esbuild@0.4.2/lodash        215.3kb
parcel/lodash                91.6kb
webpack/lodash               72.1kb
rollup/lodash                69.1kb

esbuild@0.3.9/rxjs          305.4kb
esbuild@0.4.2/rxjs          209.2kb
webpack/rxjs                 10.9kb
parcel/rxjs                   9.6kb
rollup/rxjs                   9.2kb

esbuild@0.3.9/react-icons  1567.6kb
esbuild@0.4.2/react-icons  1471.5kb
webpack/react-icons          12.6kb
parcel/react-icons            9.4kb
rollup/react-icons            9.3kb

esbuild@0.3.9/remeda         36.3kb
esbuild@0.4.2/remeda         19.9kb
webpack/remeda                2.8kb
parcel/remeda                 2.0kb
rollup/remeda                 1.9kb

esbuild@0.3.9/ramda         125.7kb
esbuild@0.4.2/ramda         106.6kb
webpack/ramda                 7.2kb
parcel/ramda                  6.4kb
rollup/ramda                  6.2kb

esbuild@0.3.9/ramdaBabel     20.6kb
esbuild@0.4.2/ramdaBabel     19.2kb
webpack/ramdaBabel            8.4kb
parcel/ramdaBabel             6.8kb
rollup/ramdaBabel             6.3kb

esbuild@0.3.9/rambda         30.7kb
parcel/rambda                 9.6kb
esbuild@0.4.2/rambda          4.2kb
webpack/rambda                2.4kb
rollup/rambda                 0.7kb

esbuild@0.3.9/rambdax        91.7kb
parcel/rambdax               22.4kb
esbuild@0.4.2/rambdax        16.2kb
webpack/rambdax               8.4kb
rollup/rambdax                6.1kb

The tree shaking in v0.4 is definitely an improvement, especially in the rambda test case.

kzc

comment created time in 5 days

issue commentevanw/esbuild

esbuild-wasm support for JS API

I'm not sure how much I trust https://github.com/mischnic/tree-shaking-example.

I just started looking through the results and I realized that at least the react-icons example is broken. A Rollup bug causes it to not find React.createElement (there are warnings during the build) and it replaces it with undefined, which would cause the generated code to crash if used.

It's definitely a useful benchmark, and is much appreciated. But I wish it had some test that the generated code is actually correct.

kzc

comment created time in 5 days

issue commentevanw/esbuild

Exposing graph information for modules.

I'm thinking of providing a slightly different format for the information, given that there are likely many use cases for it. I'm also thinking of separating out source information from chunks, otherwise you'd potentially end up repeating a lot of information and unnecessarily making the graph output bigger.

Would it be ok for your use case to use a slightly different format as long as the information you need is there? Right now I'm thinking of something like this:

interface Graph {
  sources: {
    [path: string]: {
      byteSize: number
      imports: {
        kind: 'statement' | 'require' | 'dynamic'
        path: string | null
      }[]
    }
  }
  chunks: {
    [path: string]: {
      kind: 'entry'
      byteSize: number
      sources: {
        [path: string]: {
          byteSizeInChunk: number
        }
      }
    }
  }
}
samccone

comment created time in 5 days

push eventevanw/esbuild

Evan Wallace

commit sha 87861a929937931aa53e95e668c2f98aba5f1eff

cleanup after landing PR

view details

push time in 5 days

push eventevanw/esbuild

Trung Lê

commit sha 0cefb4954834e544a5a1dd141776b71b2bf96840

Support PowerPC 64 LE architecture (#146)

view details

push time in 5 days

PR merged evanw/esbuild

Support PowerPC 64 LE architecture

This PR adds support for PowerPC64 LE Linux.

+41 -2

2 comments

6 changed files

runlevel5

pr closed time in 5 days

issue commentevanw/esbuild

Yarn PnP support

Thanks for stopping by to provide more information.

it'll spawn in daemon mode and you'll be able to interact with it through stdin/stdout

This sounds like what I had in mind for JavaScript plugins (see #111). So that confirms to me that this would probably be best as a JavaScript plugin, since it makes sense to build a mechanism like that into esbuild once, not twice. The plugin could just call out to Yarn's API.

rtsao

comment created time in 5 days

pull request commentevanw/esbuild

fix name colission: use full path instead of base

This function is called GenerateNonUniqueNameFromPath() because it shouldn't need to be unique. Name collisions are serious bugs, and should be fixed in the renamer instead. Is there an actual name collision in the generated code? Or is this more of an aesthetic improvement?

Aesthetically, a related problem that I've noticed is that there are a lot of functions named similar to require_index() from packages in node_modules that use node's implicit index.js path resolution behavior. It'd be good to fix that too.

I'm also worried about names getting to be too long. I bet just using the last two path components (immediate parent directory and file) would be a good compromise here.

There currently isn't a way to programmatically update tests. The test failures on this PR seem to demonstrate a regression in readability. It looks to me like export objects that used to have alphabetic identifiers now are named _ instead.

viankakrisna

comment created time in 6 days

issue commentevanw/esbuild

[Feature] add esbuild/register

I could see having something like this, although if it's non-trivial it's probably better as an independent 3rd-party package. Keep in mind that esbuild doesn't do type checking, so if you want type checking you'd still have to invoke the TypeScript compiler API. Also, I assume this is somewhat blocked on #136 unless you want to run execFileSync every time (which should be fine for smaller projects).

aelbore

comment created time in 6 days

issue commentevanw/esbuild

React Fast Refresh

I'm not sure this makes sense as part of esbuild. First of all esbuild is focused on production builds, not development builds. I am also trying to avoid building in complicated custom transforms for various frameworks like this. For example, I'm not planning to replicate the compiler pipelines of Vue, Svelte, or Angular either. That's why the readme says "I'm not trying to create an extremely flexible build system that can build anything."

In a world where esbuild has support for JavaScript plugins, it could potentially make sense to add this as a plugin. Or it could make sense to use esbuild's transform API to speed up another bundler that has React Fast Refresh support, and for people who want to use React Fast Refresh with esbuild to use that bundler instead.

mohsen1

comment created time in 6 days

pull request commentevanw/esbuild

Break out esbuild.CLI public Go CLI API

I see why you would like to do this. However, I don't think this is a good way to integrate esbuild into other Go apps. There would be no way to programmatically list out build errors, for example. This approach also has other issues such as causing GC to be disabled because esbuild disables GC to improve performance when invoked in batch mode.

Instead of doing this, I'd rather have an API more like the current JavaScript API. That API is future proof like this approach but also more usable. It'd be a much bigger change though, so perhaps not appropriate for a PR.

carlmjohnson

comment created time in 6 days

issue commentevanw/esbuild

Any plan for a Go API?

Not to get ahead of myself here, but for this to be practical/usable for Hugo, we would need access to the filesystem/resolver API, i.e. something more powerful than the above.

Can you say what your requirements would be explicitly? That could help inform the discussion.

I could see exposing a Go-based transform API to mirror the existing JavaScript-based API. That would let you use esbuild as a minifier or as a way to convert JSX/TypeScript to JavaScript. It's essentially the same as the stable stdin/stdout command-line interface but exposed such that you don't need to touch the file system.

bep

comment created time in 6 days

issue commentevanw/esbuild

Yarn PnP support

It doesn't seem appropriate to have this be a part of esbuild, so I don't think I would accept a PR for this. After reading https://github.com/yarnpkg/yarn/issues/6388 it looks like they deliberately made the resolution strategy depend on executing JavaScript because they want to maintain the ability to evolve the implementation. So it seems like the intended design is for the loader to call into their library.

A JavaScript plugin would be the most appropriate way to do this. Unfortunately esbuild isn't ready for JavaScript plugins. I plan to start experimenting with them at some point, and if/when I do I will keep a "resolve plugin" API in mind for this use case.

rtsao

comment created time in 6 days

pull request commentevanw/esbuild

Support PowerPC 64 LE architecture

Woah, I didn't expect someone to want to use esbuild on a platform like this. What's your use case, if you don't mind me asking? I'm curious to know where esbuild is being used.

Keep in mind that even if this PR lands, this platform won't be officially supported because it won't be covered by automated tests.

runlevel5

comment created time in 6 days

Pull request review commentevanw/esbuild

add url loader

 func parseFile( 	source := logging.Source{ 		Index:        sourceIndex, 		IsStdin:      isStdin,-		AbsolutePath: path,+		AbsolutePath: sourcePath, 		PrettyPath:   prettyPath, 		Contents:     contents, 	}  	// Get the file extension 	extension := ""-	if lastDot := strings.LastIndexByte(path, '.'); lastDot >= 0 {-		extension = path[lastDot:]+	if lastDot := strings.LastIndexByte(sourcePath, '.'); lastDot >= 0 {

Sounds good to me. I probably just wasn't aware of it existing.

viankakrisna

comment created time in 6 days

Pull request review commentevanw/esbuild

add url loader

 Options:   --jsx-factory=...     What to use instead of React.createElement   --jsx-fragment=...    What to use instead of React.Fragment   --loader:X=L          Use loader L to load file extension X, where L is-                        one of: js, jsx, ts, tsx, json, text, base64, dataurl+                        one of: js, jsx, ts, tsx, json, text, base64, url, dataurl

This feature seems similar to the Webpack file-loader plugin, so I think people will understand the name file better than url. There is also a Rollup url plugin which does something different (it does what dataurl does in esbuild), so that may also be confusing for people coming from Rollup.

viankakrisna

comment created time in 6 days

Pull request review commentevanw/esbuild

add url loader

 func parseFile( 		ast := parser.ModuleExportsAST(log, source, parseOptions, expr) 		results <- parseResult{source, ast, true} +	case LoaderURL:+		url := path.Base(sourcePath)+		targetFolder := bundleOptions.AbsOutputDir+		if targetFolder == "" {+			targetFolder = path.Dir(bundleOptions.AbsOutputFile)+		}+		defer ioutil.WriteFile(path.Join(targetFolder, url), []byte(source.Contents), 0644)

The bundler isn't supposed to write files itself. The bundler returns all of the files to be written to the caller. This makes the bundler easier to unit test and also makes it easy for the API to return results without modifying the file system (see for example #139).

Doing things this way also defeats future tree shaking optimizations, which may end up removing this module entirely. In that case the file should not be emitted in the output directory since it's unreferenced.

Instead of writing to the file system, the contents of the file should be stashed somewhere associated with the file, probably just on the parseResult or ast. Then the bundler should return the file to the caller, probably as an extra BundleResult entry. But that requires generalizing BundleResult to handle non-JavaScript result files.

viankakrisna

comment created time in 6 days

Pull request review commentevanw/esbuild

add tsconfig.json compilerOptions.paths support

 func (r *resolver) loadAsFileOrDirectory(path string) (string, bool) { 	return "", false } +func resolvePathWithoutStar(from, path string) (string, error) {+	replaced := strings.Replace(path, "/*", "", -1)+	return fp.Join(from, replaced), nil+}+ func (r *resolver) loadNodeModules(path string, dirInfo *dirInfo) (string, bool) { 	for { 		// Handle TypeScript base URLs for TypeScript code-		if dirInfo.tsConfigJson != nil && dirInfo.tsConfigJson.absPathBaseUrl != nil {-			basePath := r.fs.Join(*dirInfo.tsConfigJson.absPathBaseUrl, path)-			if absolute, ok := r.loadAsFileOrDirectory(basePath); ok {-				return absolute, true+		if dirInfo.tsConfigJson != nil {++			if dirInfo.tsConfigJson.absPathBaseUrl != nil {+				if dirInfo.tsConfigJson.paths != nil {+					for key, originalPaths := range dirInfo.tsConfigJson.paths {+						for _, originalPath := range originalPaths {+							if matched, err := regexp.MatchString("^"+key, path); matched && err == nil {+								if absoluteOriginalPath, err := resolvePathWithoutStar(*dirInfo.tsConfigJson.absPathBaseUrl, originalPath); err == nil {+									elements := strings.Split(path, "/")++									elements = elements[1:]++									resolved := append(strings.Split(absoluteOriginalPath, string(os.PathSeparator)), elements...)+									basePath := strings.Join(resolved, "/")+									if absolute, ok := r.loadAsFileOrDirectory(basePath); ok {+										return absolute, true+									}+								}+							}+						}++					}+				} else {+					basePath := r.fs.Join(*dirInfo.tsConfigJson.absPathBaseUrl, path)

It looks like the TypeScript compiler still respects baseUrl if no paths matched, so we should do that too.

viankakrisna

comment created time in 6 days

Pull request review commentevanw/esbuild

add tsconfig.json compilerOptions.paths support

 func (r *resolver) loadAsFileOrDirectory(path string) (string, bool) { 	return "", false } +func resolvePathWithoutStar(from, path string) (string, error) {+	replaced := strings.Replace(path, "/*", "", -1)+	return fp.Join(from, replaced), nil+}+ func (r *resolver) loadNodeModules(path string, dirInfo *dirInfo) (string, bool) { 	for { 		// Handle TypeScript base URLs for TypeScript code-		if dirInfo.tsConfigJson != nil && dirInfo.tsConfigJson.absPathBaseUrl != nil {-			basePath := r.fs.Join(*dirInfo.tsConfigJson.absPathBaseUrl, path)-			if absolute, ok := r.loadAsFileOrDirectory(basePath); ok {-				return absolute, true+		if dirInfo.tsConfigJson != nil {++			if dirInfo.tsConfigJson.absPathBaseUrl != nil {+				if dirInfo.tsConfigJson.paths != nil {+					for key, originalPaths := range dirInfo.tsConfigJson.paths {+						for _, originalPath := range originalPaths {+							if matched, err := regexp.MatchString("^"+key, path); matched && err == nil {

Using a regex to match this isn't correct. The pattern is an asterisk, which causes a regex to repeat the previous character zero or more times. That would mean a pattern foo* would also match a directory named foooo and fo. I took some time to look at what the TypeScript compiler itself does. The relevant code is in tryLoadModuleUsingPaths() here.

Other relevant code is tryParsePattern() here:

    export function tryParsePattern(pattern: string): Pattern | undefined {
        // This should be verified outside of here and a proper error thrown.
        Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
        const indexOfStar = pattern.indexOf("*");
        return indexOfStar === -1 ? undefined : {
            prefix: pattern.substr(0, indexOfStar),
            suffix: pattern.substr(indexOfStar + 1)
        };
    }

and isPatternMatch() here:

    function isPatternMatch({ prefix, suffix }: Pattern, candidate: string) {
        return candidate.length >= prefix.length + suffix.length &&
            startsWith(candidate, prefix) &&
            endsWith(candidate, suffix);
    }
viankakrisna

comment created time in 6 days

Pull request review commentevanw/esbuild

add tsconfig.json compilerOptions.paths support

 func (r *resolver) loadAsFileOrDirectory(path string) (string, bool) { 	return "", false } +func resolvePathWithoutStar(from, path string) (string, error) {+	replaced := strings.Replace(path, "/*", "", -1)+	return fp.Join(from, replaced), nil

The code in this file is careful to always use the fs interface in the resolver instead of path/filepath. All platform-dependent things are supposed to happen inside the fs interface so that the resolver can be platform-independent. That interface uses the real path/filepath module for the esbuild command and the path module for tests. That way tests don't do different things on Windows.

viankakrisna

comment created time in 6 days

pull request commentevanw/esbuild

add resolve-extension-order

This is an interesting feature. I'm not sure about the name --resolve-extension-order though. It's relatively long and I'm not sure I'd understand what it does given the name. What do you think about something like --implicit-extensions instead?

viankakrisna

comment created time in 6 days

issue commentevanw/esbuild

[Question] Tree shaking

If a side effect free file within a module is imported and no symbols are used from it, then the import can be dropped altogether.

Yes, that model makes sense to me. That's the trivial way to do things safely.

To use a garbage collector analogy, any used exports or top level statements with side effects are considered to be roots.

This is what I've implemented in the latest release.

But if any exported symbol is imported from a side effect free file then its top level statements with side effects must be retained, and only its unreferenced symbols without side effects may be dropped.

Since code is JavaScript, it's impossible to determine what is guaranteed to be free of side effects outside of a whitelist of a few types of expressions such as literals. I was wondering if the "sideEffects": false annotation somehow biases the compiler's determination of what is side-effect free. For example, you might have code like this:

export function foo() {}
foo.bar = 123

It's impossible to determine based on this code whether the second statement has side effects or not. Someone might have done this somewhere before this was evaluated:

Object.defineProperty(Function.prototype, 'bar', {
  set() {
    sideEffects()
  }
})

And if the second statement is retained then the first line must also be retained. I'm wondering if "sideEffects": false is supposed to mean something like "trust me these property accesses don't have side effects". Otherwise tree shaking isn't going to do that much in the benchmarks you referenced.

I could see an alternative algorithm where, if "sideEffects": false is present, code with side-effects can form a connected component in the top-level statement graph but connected components could still be dropped if there are no references into the connected component from the outside (also similar to garbage collection). But referencing something in the connected component would pull in the whole connected component (so referencing foo would also pull in the assignment to foo.bar.

amursky

comment created time in 6 days

issue commentevanw/esbuild

Move to org

Yes I'm planning to do this at some point. I have already reserved an org, I just haven't made the switch yet: https://github.com/esbuild.

DanielRuf

comment created time in 6 days

issue commentevanw/esbuild

Yarn PnP support

No I haven't. As you pointed out, it's not a good fit for esbuild because the module resolution involves executing arbitrary JavaScript code instead of following a well-defined algorithm.

I'm not sure if it's a valid alternative, but you could consider pnpm instead. That uses symlinks as a faster alternative to node_modules and esbuild has been updated to support it: #67.

It's possible that esbuild might have some form of "resolve plugin" API in the future which would make this possible. Either that or it could potentially expose an API that would let you build your own bundler that supports PnP and uses esbuild as a backend. But such an API won't be coming soon because esbuild isn't that mature yet.

rtsao

comment created time in 6 days

created tagevanw/esbuild

tagv0.4.2

An extremely fast JavaScript bundler and minifier

created time in 6 days

push eventevanw/esbuild

Evan Wallace

commit sha 45dc7e7237638e7429b359c494b1279fad46f5ad

publish 0.4.2 to npm

view details

push time in 6 days

push eventevanw/esbuild

Evan Wallace

commit sha bf457c314eab2470a8a85139aaf607db0e7c3c34

fix #149: bind imports to all intermediate re-exports

view details

push time in 6 days

issue closedevanw/esbuild

Multiple imports from different files from one file are imported wrong with esm module

At first, let me sincerely thank for your efforts. What an extraordinary speed in a bundler, and i have tried all of them.

Unfortunately i have found a bug.

If you define esm as output format, and are importing from different files the same method, i believe something is not like it should be.

First file app.js:

import { p as Part, h, render } from './import';
import { Internal } from './in2';
const App = () => <Part> <Internal /> T </Part>;
render(<App />, document.getElementById('app'));

Second file in2.js:

import { p as Part, h } from './import';
export const Internal = () => <Part> Test 2 </Part>;

Third file import.js:

import { h, render } from 'preact';
export const p = "p";
export { h, render }

output:

// src/import.js
import {h, render} from "preact";
const p = "p";

// src/in2.js
const Internal = () => h3(p, null, " Test 2 ");

// src/in.js
const App = () => h2(p, null, h2(Internal, null), " T ");
render2(h2(App, null), document.getElementById("app"));

Note the broken h2, render2, h3 functions.

Preact is marked as external file, output format esm. Yes i know this is an uncommon way of doing it. But, in other bundlers, output bundle is smaller, because the reexported function is only referenced once, and i am able to reuse it, and its possible to reexport it with the same name. What is important, with h and render in react/preact ...

Thank you.

closed time in 6 days

a-gerescher

issue commentevanw/esbuild

Multiple imports from different files from one file are imported wrong with esm module

Thank you for the clear description of what's wrong and for the minimal test case. It looks like I'm not binding imports to re-exports. I'm surprised I haven't run into this issue yet with all of my testing. This will be fixed soon.

a-gerescher

comment created time in 6 days

created tagevanw/esbuild

tagv0.4.1

An extremely fast JavaScript bundler and minifier

created time in 6 days

push eventevanw/esbuild

Evan Wallace

commit sha b53cba406954140d225c83751698a35827292e9f

publish 0.4.1 to npm

view details

push time in 6 days

push eventevanw/esbuild

Ade Viankakrisna Fadlil

commit sha 3af5a9fe53ea5de020d0eff5d2f9846713261a27

add editorconfig (#145)

view details

push time in 6 days

PR merged evanw/esbuild

add editorconfig

not sure what's the preference here :thinking: this is mainly done so diffs on PRs are easier to read

+3 -0

0 comment

1 changed file

viankakrisna

pr closed time in 6 days

push eventevanw/esbuild

Evan Wallace

commit sha e11e4741d67cee7e8679956ae2389887c2a1499f

move all commonjs chunks up to fix cyclic imports

view details

push time in 6 days

issue commentevanw/esbuild

Update the fuse-box benchmark

Do you have any plans on splitting it into packages ? Like parser, printer, minifier ?

I don't have any plans to do that at the moment. However, I do have a JavaScript API for transforming code using esbuild. It can be used to minify code if you pass minify: true.

nchanged

comment created time in 6 days

push eventevanw/esbuild

Evan Wallace

commit sha dd418175e2b5beccd7a20110dc30a4505237a77e

various fixes for future syntax errors

view details

push time in 6 days

push eventevanw/esbuild

Evan Wallace

commit sha 84e7bb970d733ed377e342e24e8b41fcaf72a9ce

fix #129: call out chinese translation in changelog

view details

push time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha 48bf9b642b2deae4dc86407dcb02ca1522aa9023

fix #129: call out chinese translation in changelog

view details

push time in 7 days

issue closedevanw/esbuild

[docs] I contribute Chinese docs to esbuild.

I translated the esbuild docs into Chinese: http://docs.breword.com/evanw-esbuild

And i posted the docs on some frontend community websites which are popular in China,many developers view it and know esbuild.

@evanw , If possible, i want to write a PR to add the Chinese docs link in readme.md to make esbuild spread more widely, or push the Chinese docs into esbuild repo.

Thanks.

closed time in 7 days

92hackers

push eventevanw/esbuild

Evan Wallace

commit sha 47d82118b96da35e908dea2c434a8d9b4f4554c9

capitalize architecture

view details

push time in 7 days

push eventevanw/esbuild

CHEN Yuan

commit sha 9d2242d9cb06da1a718b7b88d5ee61a767b08f3b

Add: add Chinese docs link to README.md (#143)

view details

push time in 7 days

PR merged evanw/esbuild

Add: add Chinese docs link to README.md

@evanw , If the position of documentation section in README.md is not what you want or something else, comment it and i will modify.

And, i will continue maintain the Chinese docs of this project once it connects with repo.

Thanks

+5 -0

1 comment

1 changed file

92hackers

pr closed time in 7 days

pull request commentevanw/esbuild

Add: add Chinese docs link to README.md

Awesome! Thanks so much for doing all of this translation work.

92hackers

comment created time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha 11e268a1ee2fd5605770157aa847e5a8731796cc

fixes for jsconfig.json support

view details

push time in 7 days

push eventevanw/esbuild

Ade Viankakrisna Fadlil

commit sha 5ed44e60481aa04100e4b203fd7b7445279ee8b3

add jsconfig support (#132)

view details

push time in 7 days

PR merged evanw/esbuild

add jsconfig support
+82 -25

2 comments

2 changed files

viankakrisna

pr closed time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha 6dc65d088007874261246141edceaa9eaa165a4e

fix #117: add a log level setting

view details

push time in 7 days

issue closedevanw/esbuild

silent flag

Would you consider adding a --silent or --verbose flag to allow output only errors?

closed time in 7 days

scorredoira

issue commentevanw/esbuild

[Question] Tree shaking

Yeah I'll have to study the test cases, and do some reverse engineering to answer some of my questions. I read the documentation but it was too high-level and didn't really tell me enough information to implement it.

I just released version 0.4.0 which has the preliminary tree shaking support described above. Please try it out and let me know if you encounter any correctness issues. As I said above, esbuild isn't respecting annotations yet so the size is likely still going to be bigger than other bundlers. Right now tree shaking is only based on which top-level statements reference which other top-level statements. I'll do another push later on to improve on bundle sizes.

amursky

comment created time in 7 days

issue closedevanw/esbuild

Export ES6 module

Now created bundle has commonjs format. Is there any way to set bundle format to esm?

closed time in 7 days

dy

issue commentevanw/esbuild

Export ES6 module

This is implemented in version 0.4.0 that was just released. Please try it out and let me know if you find any issues.

dy

comment created time in 7 days

issue commentevanw/esbuild

Update the fuse-box benchmark

I just updated the versions of all packages used in the benchmark and it looks like the latest version of fuse-box@next pretty much passes my tests for a valid benchmark entry. So I included it and I'm considering this issue fixed. The only caveat I found as far as correctness was that the line numbers for the source map generated by fuse-box seem to be off by one. And with the update, fuse-box is no longer the slowest bundler in my benchmark! It's great to see these performance improvements.

nchanged

comment created time in 7 days

delete branch evanw/esbuild

delete branch : v0.4

delete time in 7 days

created tagevanw/esbuild

tagv0.4.0

An extremely fast JavaScript bundler and minifier

created time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha be54c90fc3ca8e9f771ed1ec6c4996697360d7e9

no need to pass a pointer to symbol map

view details

Evan Wallace

commit sha 7727572ac61b5fe96319a920a8b201d51759a9fd

parse each top-level statement into a part

view details

Evan Wallace

commit sha 34d618ec766806c12d55bddc257bde413b7a42dd

add side-effect detection code

view details

Evan Wallace

commit sha 935d2b13b426807caa3620be830102f49d71b5dc

track part-to-part dependencies within a file

view details

Evan Wallace

commit sha 411df3dadc95ea24e5800452344914e45326b49d

track export-to-part dependencies

view details

Evan Wallace

commit sha 7bc9cdcbfdc24bc127ab22540db17b94a5785095

track imports as declared symbols

view details

Evan Wallace

commit sha 91856c89d99edab8697d58990e6ac62ed41a0c26

add the "es" output format option

view details

Evan Wallace

commit sha cb0d60f8d22526212270043732bfcdc10a8aaa93

start work on the linker

view details

Evan Wallace

commit sha f36aca1241c85923589e958cc3ef74cc07366a67

start work on code generation

view details

Evan Wallace

commit sha 9cb931dbd54607d7b09646ca772330123689445a

make runtime more like a normal module

view details

Evan Wallace

commit sha ad06e025f26678870bb01350cdab5e66201fdf9b

get source maps working again

view details

Evan Wallace

commit sha 6080586667e3bd326c390c22f05958dbc24abf53

delete old unused code

view details

Evan Wallace

commit sha f7d71bd8bcbea749d41c63c8f22779223a371a22

remove old independent mode

view details

Evan Wallace

commit sha ef8a34c92a81b38e427144db5831dc8849304756

fixes for no-bundle mode

view details

Evan Wallace

commit sha 7449d42f642a18b953e78b76ef6e861988cd7c2e

re-implement star imports

view details

Evan Wallace

commit sha eab187755b48bc501c699413a0a85b9451527087

re-implement star exports

view details

Evan Wallace

commit sha aaca12e35ec4cfa6a8a172d0de122c5c21be09df

immediately evaluate commonjs entry points

view details

Evan Wallace

commit sha f7d5af7f93ef7d22064e2349be6394d5cf9cfa47

change how export parts are generated

view details

Evan Wallace

commit sha a97f18b6d2c0ae68c955633aba81a9803d769c71

rewrite export parts again to fix bugs

view details

Evan Wallace

commit sha 038a06a9965bd4a614ffa0bff985bba30a713ca0

bring back parallelism

view details

push time in 7 days

issue closedevanw/esbuild

Update the fuse-box benchmark

Hi, First of all, I would like to say I appreciate your effect and the project. Good Job! I love open source myself and love seeing people do some awesome stuff! Keep up!

That said, I would like to suggest to set up a proper benching for FuseBox with the latest version. The @next version is outdated since it has undergone a full a refactor and I am publishing it with the alpha tag

FuseBox now has its own custom compiler that managed to pass your bench in 6 seconds. And it will be even faster when we publish it.

If possible, could you include development builds? Production versions are always slower for a reason. After all, development experience is what matters most.

fuse-box@4.0.0-alpha.307

Development run

FUSEBOX_RUN += require('fuse-box').fusebox({
FUSEBOX_RUN +=   target: 'browser',
FUSEBOX_RUN +=   hmr: false,
FUSEBOX_RUN +=   devServer : false,
FUSEBOX_RUN +=   watcher : false,
FUSEBOX_RUN +=   logging: {level : 'disabled'},
FUSEBOX_RUN +=   entry: './fusebox-entry.js',
FUSEBOX_RUN += }).runDev({ bundles : {app : 'app.js'}});

Results:

real 6.01
user 7.22
sys 0.57

Prod run

FUSEBOX_RUN += require('fuse-box').fusebox({
FUSEBOX_RUN +=   target: 'browser',
FUSEBOX_RUN +=   logging: {level : 'disabled'},
FUSEBOX_RUN +=   entry: './fusebox-entry.js',
FUSEBOX_RUN += }).runProd({ bundles : {app : 'app.js'}});

results:

real 30.89
user 44.42

I'd really appreciate the above-mentioned fixes to the benches and updated stats.

Thanks ;-)

closed time in 7 days

nchanged

issue commentegoist/rollup-plugin-esbuild

[feature] log error details/context to console

This is unfortunate. I didn't include the errors here because esbuild can potentially generate hundreds of errors and I didn't want the exception string to ever be huge. The errors are in an array in the errors property on the exception. But I can definitely include the first few errors in the exception message. I'm sure this library isn't the only one with this problem. This will be in the new 0.4.0 release that will be coming sometime soon.

bmcminn

comment created time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha 83456ad71c633a4612c0909d4c94a7356e7aaf32

revert format controls in try.html

view details

push time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha a2ad0a082382b4ad96a43889d8b5e2c71a7f9e32

add note about architecture doc being outdated

view details

push time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha bec3d2a4e8b432bb02ac9291971f4dd9fbc0c58c

update benchmarks (fixes #26)

view details

push time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha 442ed6eef99b98bab940ea38bf426b59025b7c5b

js api: include first few errors in exception

view details

push time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha e889f0506696589cb17e95e533335a31fc5ea686

add warning for guaranteed missing commonjs imports

view details

push time in 7 days

issue closedevanw/esbuild

`assert` module import is transformed incorrectly

I do assert module import like this in typescript:

import * as assert from 'assert';
...
assert(serviceUrl?.length, `Cannot initialize service ${serviceName}`);

and I'm getting error in runtime "TypeError: assert5 is not a function"

Following the stack trace, I see that it was transformed like:

const assert5 = __toModule(require("assert"));
...
assert5(serviceUrl == null ? void 0 : serviceUrl.length, `Cannot initialize service ${serviceName}`);

but the assert5 function invokation is supposed to be transformed to assert5.default the same way like I would import it using default import:

import assert from 'assert';

So import * as assert from 'assert'; is not transformed correctly. I see that this kind of import is covered by tests on fs module example, but apparently the case that default export is a function is not covered.

closed time in 7 days

floydspace

issue commentevanw/esbuild

`assert` module import is transformed incorrectly

Just saw you gave a 👍. Closing as "working as intended".

floydspace

comment created time in 7 days

issue commentevanw/esbuild

[Question] Tree shaking

Thanks for these links! These are very helpful.

I have tree shaking basically implemented, and about to be released. It's currently in a branch as I test it and prepare it for release. This release is going to be about correctness, not minimal bundle sizes. It introduces the tree shaking data structure but doesn't yet handle the side-effect annotations you mention in https://github.com/evanw/esbuild/issues/86#issuecomment-625923444. That will have to come in subsequent releases.

Is there information anywhere about how the "sideEffects" hint is supposed to work? Using it to remove the whole module if it's unreferenced makes sense to me. I'm wondering if it's supposed to be used to infer something about the top-level statements in the file not having side-effects too.

amursky

comment created time in 7 days

delete branch evanw/esbuild

delete branch : v4

delete time in 7 days

create barnchevanw/esbuild

branch : v0.4

created branch time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha c973f9e625426f23c2cbd5e1f5cb71de7b3c4f2f

breaking change: future syntax is now an error

view details

Evan Wallace

commit sha b6ed365d350ac01659e06f715425faeb2866637d

update changelog

view details

Evan Wallace

commit sha 5e9d45ce8289c72adc26e641e537792a20c27671

"this" is undefined for es6 and "exports" for cjs

view details

Evan Wallace

commit sha bd6c82beb917e522eeb70e39b86d8d544e131232

don't need __toModule when not bundling

view details

push time in 7 days

push eventevanw/esbuild

Evan Wallace

commit sha 818954c35c0281324f7e064f782eac4eba743663

don't need __toModule when not bundling

view details

push time in 7 days

create barnchevanw/esbuild

branch : v4

created branch time in 7 days

issue commentevanw/esbuild

In memory output of Build API (adding write: boolean)

I would like to do this. The underlying transport mechanism for the API is already built this way, but the API currently only exposes the ability to transform a single file. So it's definitely possible to do this.

aelbore

comment created time in 8 days

more