In our previous post, we used esbuild
to transpile, bundle and minify a very simple react-native-web
project.
Now, in this post, let's try a more complex project, a clone of the GoogleFit app. The original repository is https://github.com/Chandankkrr/googlefit and the author wrote an article about how he built the app.
We choose this project because it uses Typescript, Expo, react-navigation 5.0, react-native-svg and react-native-paper.
Previous setup
First of all, let's remember what we did in the last post:
- Install Esbuild:
npm i -g esbuild
ornpm i esbuild
. - Create a
./web/index.html
file - Alias
react-native
toreact-native-web
in thetsconfig.json
.{"compilerOptions": {..., "baseUrl": ".", "paths": {"react-native": ["./node_modules/react-native-web"]}}}
- Execute Esbuild with this command:
esbuild --bundle node_modules/expo/AppEntry.js --outfile=./web/bundle.js --resolve-extensions=.web.tsx,.web.ts,.web.jsx,.web.js,.tsx,.ts,.jsx,.js --loader:.js=jsx '--define:process.env.NODE_ENV="production"' --tsconfig=tsconfig.json --minify --sourcemap
. - The command can be replaced for a build script:
require('esbuild').build({
entryPoints: ['./node_modules/expo/AppEntry.js'],
bundle: true,
outfile: './web/bundle.js',
tsconfig: 'jsconfig.json',
define: {'process.env.NODE_ENV': '"production"'},
resolveExtensions: ['.web.jsx','.web.js','.jsx','.js',],
minify: true,
sourcemap: true
}).catch(() => process.exit(1))
Fixing the issues
Running the above command, we will see several errors related to the .png and .font files. To fix it, we need to include the following arguments in our command: --loader:.png=file --loader:.ttf=file
. It will copy these files to the web directory.
We also need to change jsconfig.json
to tsconfig.json
and included the extensions .web.tsx,.web.ts,.tsx,.ts
, because we are using Typescript now.
Some libraries use .js
files for JSX instead of .jsx
. To guide Esbuild how to use .js
with React, we need to include --loader:.js=jsx
in the command line or the loader {".js": "jsx"}
in the build script.
After building the app, when we open the HTML page, the browser complains that global
and __DEV__
are not define. Therefore, we need to include --define:__DEV__=false --define:global=window
in the command line or define: {'process.env.NODE_ENV': '"production"', '__DEV__': false, global:'window'}
in the build script. process.env.NODE_ENV
and__DEV__
must be defined appropriately, according to the environment.
The new command line is:
$ esbuild ./node_modules/expo/AppEntry.js --bundle --outfile=./web/bundle.js --resolve-extensions=.web.tsx,.web.ts,.web.jsx,.web.js,.tsx,.ts,.jsx,.js --loader:.js=jsx --loader:.png=file --loader:.ttf=file --tsconfig=tsconfig.json --define:__DEV__=false --define:process.env.NODE_ENV='\"production\"' --define:global=window --sourcemap --minify
And the new build script:
require('esbuild').build({
entryPoints: ['./node_modules/expo/AppEntry.js'],
bundle: true,
outfile: './web/bundle.js',
tsconfig: 'tsconfig.json',
define: {'process.env.NODE_ENV': '"production"', '__DEV__': false, global:'window'},
loader: {".png": "file", ".ttf": "file", ".js": "jsx" },
resolveExtensions: ['.web.tsx','.web.ts','.web.jsx','.web.js','.tsx','.ts','.jsx','.js',],
minify: true,
sourcemap: true,
}).catch(() => process.exit(1))
Result:
Plugins
Some react-native libraries like react-native-gesture-handler
are distributed without transpilation and with Flow types annotations. Esbuild doesn't work with Flow out of the box. But Esbuild now supports plugins.
It is not possible to use plugins with the command line, therefore, we need to use the build script.
First, we need to install the plugin: npm i esbuild-plugin-flow
.
Next, we need require or import the package and to include this line in the build script: plugins: [flow(/node_modules\\react-native-gesture-handler.*\.jsx?$/)]
.
It is not necessary for this example (GoogleFit app).
Why Esbuild?
The big question is, why to use Esbuild instead of WebPack or Metro?
The answers are easy to set up, as we could see, and performance.
In our next post, we will explore the performance of Esbuild compared with these alternatives.
Top comments (0)