@ethicdevs/metro-webpack-react-native-web-babel-preset
A babel preset that configures itself for both metro with react-native and webpack with react-native-web. Use this instead of module:metro-react-native-babel-preset
in your Babel config file.
Usage
Install with either npm or yarn (as you prefer). core-js@3
is a peer dependency and you might need to install it seperately.
yarn add -D core-js@3 @ethicdevs/metro-webpack-react-native-web-babel-preset
Add this to your Babel config file (babel.config.js
):
module.exports = {
presets: ["@ethicdevs/metro-webpack-react-native-web-babel-preset"],
};
noPresetEnv
option
With If you want to provide your own preset-env config (in babel.config.js
or babel-loader
config, etc), you can exclude @babel/preset-env
with the option noPresetEnv
.
module.exports = {
presets: [
["@ethicdevs/metro-webpack-react-native-web-babel-preset", { noPresetEnv: true }],
],
};
Behaviour
When bundling with metro, it simply includes module:metro-react-native-babel-preset
so it shouldn't mess with your normal react native build.
When bundling with webpack/babel-loader, it includes the presets for typescript and flow, the react-native-web plugin, and the plugins from module:metro-react-native-babel-preset
that aren't better handled by @babel/preset-env
: react/jsx specific stuff and proposal features. It also includes @babel/preset-env
set up to automatically pick up .browserslistrc
or browserlist
key in package.json
and include appropriate polyfills.
When running in any other environment, it falls back to the same config as for webpack.
Using with webpack
With this preset, you can bundle a basic react native app for the web with very little or technically no webpack config.
You need to install at least webpack
, babel-loader
and probably babel-cli
.
A minimal webpack.config.js
would be:
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx|tsx|ts|mjs)$/,
include: [path.resolve(__dirname, "src")],
use: {
loader: "babel-loader",
},
},
],
},
resolve: {
extensions: [
".web.js",
".js",
".web.ts",
".ts",
".web.tsx",
".tsx",
".web.mjs",
".mjs",
],
},
};
And technically no config file with this command (doesn't work great though)
npx webpack --module-bind js=babel-loader
Don't forget to add a .browserslistrc
to your root directory or your bundle will be huge. For example:
>0.5%
not ie 11
not samsung < 8
Magic bit
module.exports = ({ caller }) => {
// is either "metro" or "babel-loader"
const runningIn = caller(({ name }) => name);
return {
/* your config here */
};
};
Changelog
- 1.4.1 add note to readme
- 1.4.0 require() all babel presets and plugins so they can be resolved even if they are installed in nested node_modules. Is this what you're supposed to do? Well it works...
- 1.3.1 actually add it as a dependency, should have started on 0.x
- 1.3.0 make core-js a peer dependecy
- 1.2.0 add
babel-plugin-react-native-web
as dependency, oops - 1.1.0 add
babel-plugin-module-resolver
as dependency - 1.0.0 Initial Release