Re.pack Rspack (5.0.0-alpha.0) - Panic occurred at runtime. Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.
Describe the bug
I am trying to upgrade from @callstack/repack v4 to v5.0.0-alpha.0. I have followed the templates in the repack example as well as the official webpack -> rspack migration documentation to migrate from webpack to rspack.
I have a react-native super-app that leverages module-federation and exists as a monorepo.
Here's what my rspack.config.mjs file looks like for the host:
export default (env) => {
console.log('using mobile webpack config...');
const {
mode = 'development',
context = Repack.getDirname(import.meta.url),
entry = './index.js',
platform = process.env.PLATFORM,
minimize = mode === 'production',
devServer = undefined,
bundleFilename = undefined,
sourceMapFilename = undefined,
assetsPath = undefined,
reactNativePath = new URL('./node_modules/react-native', import.meta.url)
.pathname,
} = env;
const dirname = Repack.getDirname(import.meta.url);
if (!platform) {
throw new Error('Missing platform');
}
/**
* Depending on your Babel configuration you might want to keep it.
* If you don't use `env` in your Babel config, you can remove it.
*
* Keep in mind that if you remove it you should set `BABEL_ENV` or `NODE_ENV`
* to `development` or `production`. Otherwise your production code might be compiled with
* in development mode by Babel.
*/
process.env.BABEL_ENV = mode;
return {
mode,
/**
* This should be always `false`, since the Source Map configuration is done
* by `SourceMapDevToolPlugin`.
*/
devtool: false,
context,
/**
* `getInitializationEntries` will return necessary entries with setup and initialization code.
* If you don't want to use Hot Module Replacement, set `hmr` option to `false`. By default,
* HMR will be enabled in development mode.
*/
entry,
resolve: {
/**
* `getResolveOptions` returns additional resolution configuration for React Native.
* If it's removed, you won't be able to use `<file>.<platform>.<ext>` (eg: `file.ios.js`)
* convention and some 3rd-party libraries that specify `react-native` field
* in their `package.json` might not work correctly.
*/
...Repack.getResolveOptions(platform),
tsConfig: './tsconfig.json',
},
/**
* Configures output.
* It's recommended to leave it as it is unless you know what you're doing.
* By default Webpack will emit files into the directory specified under `path`. In order for the
* React Native app use them when bundling the `.ipa`/`.apk`, they need to be copied over with
* `Repack.OutputPlugin`, which is configured by default inside `Repack.RepackPlugin`.
*/
output: {
clean: true,
hashFunction: 'xxhash64',
path: path.join(dirname, 'build/generated', platform),
filename: 'index.bundle',
chunkFilename: '[name].chunk.bundle',
publicPath: Repack.getPublicPath({ platform, devServer }),
},
/**
* Configures optimization of the built bundle.
*/
optimization: {
/** Enables minification based on values passed from React Native CLI or from fallback. */
minimize,
/** Configure minimizer to process the bundle. */
minimizer: [
new TerserPlugin({
test: /\.(js)?bundle(\?.*)?$/i,
/**
* Prevents emitting text file with comments, licenses etc.
* If you want to gather in-file licenses, feel free to remove this line or configure it
* differently.
*/
extractComments: false,
terserOptions: {
format: {
comments: false,
},
},
}),
],
chunkIds: 'named',
},
module: {
rules: [
Repack.REACT_NATIVE_LOADING_RULES,
Repack.NODE_MODULES_LOADING_RULES,
/* repack is symlinked to a local workspace */
{
test: /\.[jt]sx?$/,
type: 'javascript/auto',
include: [/repack[/\\]dist/],
use: {
loader: 'builtin:swc-loader',
options: {
env: { targets: { 'react-native': '0.74' } },
jsc: { externalHelpers: true },
},
},
},
/* codebase rules */
{
test: /\.[jt]sx?$/,
type: 'javascript/auto',
exclude: [/node_modules/, /repack[/\\]dist/],
use: {
loader: 'builtin:swc-loader',
/** @type {import('@rspack/core').SwcLoaderOptions} */
options: {
sourceMaps: true,
env: {
targets: { 'react-native': '0.74' },
},
jsc: {
parser: {
syntax: 'typescript',
},
externalHelpers: true,
transform: {
react: {
runtime: 'automatic',
},
},
},
},
},
},
{
test: Repack.getAssetExtensionsRegExp(Repack.ASSET_EXTENSIONS),
use: {
loader: '@callstack/repack/assets-loader',
options: {
platform,
devServerEnabled: Boolean(devServer),
},
},
},
],
},
plugins: [
new rspack.IgnorePlugin({ resourceRegExp: /@react-native-masked-view/ }),
/**
* Configure other required and additional plugins to make the bundle
* work in React Native and provide good development experience with
* sensible defaults.
*
* `Repack.RepackPlugin` provides some degree of customization, but if you
* need more control, you can replace `Repack.RepackPlugin` with plugins
* from `Repack.plugins`.
*/
new Repack.RepackPlugin({
context,
mode,
platform,
devServer,
output: {
bundleFilename,
sourceMapFilename,
assetsPath,
},
}),
new Repack.plugins.ModuleFederationPlugin({
name: 'host',
shared: {
react: {
...Repack.Federated.SHARED_REACT,
requiredVersion: '18.2.0',
eager: true,
},
'react-native': {
...Repack.Federated.SHARED_REACT_NATIVE,
requiredVersion: '0.74',
eager: true,
},
reselect: {
singleton: true,
requiredVersion: monorepoDeps['reselect'],
eager: true,
},
'react-redux': {
singleton: true,
requiredVersion: monorepoDeps['react-redux'],
eager: true,
},
'@reduxjs/toolkit': {
singleton: true,
requiredVersion: monorepoDeps['@reduxjs/toolkit'],
eager: true,
},
'@reduxjs/toolkit/query': {
singleton: true,
requiredVersion: monorepoDeps['@reduxjs/toolkit/query'],
eager: true,
},
'@reduxjs/toolkit/query/react': {
singleton: true,
requiredVersion: monorepoDeps['@reduxjs/toolkit/query/react'],
eager: true,
},
'@react-navigation/native': {
singleton: true,
requiredVersion: monorepoDeps['@react-navigation/native'],
eager: true,
},
'@react-navigation/native-stack': {
singleton: true,
requiredVersion: monorepoDeps['@react-navigation/native-stack'],
eager: true,
},
'react-native-screens': {
singleton: true,
requiredVersion: monorepoDeps['react-native-screens'],
eager: true,
},
'react-native-safe-area-context': {
singleton: true,
requiredVersion: monorepoDeps['react-native-safe-area-context'],
eager: true,
},
'redux-persist': {
singleton: true,
requiredVersion: monorepoDeps['redux-persist'],
eager: true,
},
'@react-native-async-storage/async-storage': {
singleton: true,
requiredVersion:
monorepoDeps['@react-native-async-storage/async-storage'],
eager: true,
},
},
}),
new rspack.EnvironmentPlugin({ MF_CACHE: null }),
process.env.RSDOCTOR && new RsdoctorRspackPlugin(),
].filter(Boolean),
};
};
When I try to start the host app using the command: react-native webpack-start --webpackConfig ./rspack.config.mjs --host 127.0.0.1, I get the following error:
Panic occurred at runtime. Please file an issue on GitHub with the backtrace below: https://github.com/web-infra-dev/rspack/issues
Message: Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.
Location: crates/rspack_binding_options/src/options/raw_devtool.rs:99
My motivation, and need, to get to Rspack from Webpack is to lower the build time it currently takes with webpack. The fact that with callstack/repack v4 we need to use webpack and babel-loader to transpile huge node_module files (for react-native compatibility) is a pain and leads to really slow compilation of the host and other mini-apps that have bare minimal code (2-4 source files).
I have learnt that swc is a much faster alternative to babel-loader and hence I'd love to be able to leverage it in my project setup.
Any help with resolving this issue and getting my project to successfully work with @callstack/repack v5.0.0-alpha.0 and rspac + swc-loader would be highly appreciated.
Thanks !
System Info
System:
OS: macOS 14.5
CPU: (10) arm64 Apple M1 Max
Memory: 104.30 MB / 64.00 GB
Shell:
version: 3.2.57
path: /bin/bash
Binaries:
Node:
version: 18.18.0
path: ~/.nvm/versions/node/v18.18.0/bin/node
Yarn:
version: 1.19.0
path: /opt/homebrew/bin/yarn
npm:
version: 9.8.1
path: ~/.nvm/versions/node/v18.18.0/bin/npm
Watchman: Not Found
Managers:
CocoaPods:
version: 1.15.2
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK: Not Found
Android SDK: Not Found
IDEs:
Android Studio: 2021.3 AI-213.7172.25.2113.9123335
Xcode:
version: /undefined
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.5
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react: Not Found
react-native:
installed: 0.74.5
wanted: "0.74"
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: false
iOS:
hermesEnabled: true
newArchEnabled: false
Re.Pack Version
5.0.0-alpha.0
Reproduction
n/a
Steps to reproduce
Use the following config for rspack.config.js :
import path from 'path';
import TerserPlugin from 'terser-webpack-plugin';
import * as Repack from '@callstack/repack';
import monorepoPackage from '../../package.json' assert { type: 'json' };
import rspack from '@rspack/core';
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin';
const monorepoDeps = monorepoPackage.dependencies;
/**
* More documentation, installation, usage, motivation and differences with Metro is available at:
* https://github.com/callstack/repack/blob/main/README.md
*
* The API documentation for the functions and plugins used in this file is available at:
* https://re-pack.netlify.app/
*/
/**
* Webpack configuration.
* You can also export a static object or a function returning a Promise.
*
* @param env Environment options passed from either Webpack CLI or React Native CLI
* when running with `react-native start/bundle`.
*/
export default (env) => {
console.log('using mobile webpack config...');
const {
mode = 'development',
context = Repack.getDirname(import.meta.url),
entry = './index.js',
platform = process.env.PLATFORM,
minimize = mode === 'production',
devServer = undefined,
bundleFilename = undefined,
sourceMapFilename = undefined,
assetsPath = undefined,
reactNativePath = new URL('./node_modules/react-native', import.meta.url)
.pathname,
} = env;
const dirname = Repack.getDirname(import.meta.url);
if (!platform) {
throw new Error('Missing platform');
}
/**
* Depending on your Babel configuration you might want to keep it.
* If you don't use `env` in your Babel config, you can remove it.
*
* Keep in mind that if you remove it you should set `BABEL_ENV` or `NODE_ENV`
* to `development` or `production`. Otherwise your production code might be compiled with
* in development mode by Babel.
*/
process.env.BABEL_ENV = mode;
return {
mode,
/**
* This should be always `false`, since the Source Map configuration is done
* by `SourceMapDevToolPlugin`.
*/
devtool: false,
context,
/**
* `getInitializationEntries` will return necessary entries with setup and initialization code.
* If you don't want to use Hot Module Replacement, set `hmr` option to `false`. By default,
* HMR will be enabled in development mode.
*/
entry,
resolve: {
/**
* `getResolveOptions` returns additional resolution configuration for React Native.
* If it's removed, you won't be able to use `<file>.<platform>.<ext>` (eg: `file.ios.js`)
* convention and some 3rd-party libraries that specify `react-native` field
* in their `package.json` might not work correctly.
*/
...Repack.getResolveOptions(platform),
tsConfig: './tsconfig.json',
},
/**
* Configures output.
* It's recommended to leave it as it is unless you know what you're doing.
* By default Webpack will emit files into the directory specified under `path`. In order for the
* React Native app use them when bundling the `.ipa`/`.apk`, they need to be copied over with
* `Repack.OutputPlugin`, which is configured by default inside `Repack.RepackPlugin`.
*/
output: {
clean: true,
hashFunction: 'xxhash64',
path: path.join(dirname, 'build/generated', platform),
filename: 'index.bundle',
chunkFilename: '[name].chunk.bundle',
publicPath: Repack.getPublicPath({ platform, devServer }),
},
/**
* Configures optimization of the built bundle.
*/
optimization: {
/** Enables minification based on values passed from React Native CLI or from fallback. */
minimize,
/** Configure minimizer to process the bundle. */
minimizer: [
new TerserPlugin({
test: /\.(js)?bundle(\?.*)?$/i,
/**
* Prevents emitting text file with comments, licenses etc.
* If you want to gather in-file licenses, feel free to remove this line or configure it
* differently.
*/
extractComments: false,
terserOptions: {
format: {
comments: false,
},
},
}),
],
chunkIds: 'named',
},
module: {
rules: [
Repack.REACT_NATIVE_LOADING_RULES,
Repack.NODE_MODULES_LOADING_RULES,
/* repack is symlinked to a local workspace */
{
test: /\.[jt]sx?$/,
type: 'javascript/auto',
include: [/repack[/\\]dist/],
use: {
loader: 'builtin:swc-loader',
options: {
env: { targets: { 'react-native': '0.74' } },
jsc: { externalHelpers: true },
},
},
},
/* codebase rules */
{
test: /\.[jt]sx?$/,
type: 'javascript/auto',
exclude: [/node_modules/, /repack[/\\]dist/],
use: {
loader: 'builtin:swc-loader',
/** @type {import('@rspack/core').SwcLoaderOptions} */
options: {
sourceMaps: true,
env: {
targets: { 'react-native': '0.74' },
},
jsc: {
parser: {
syntax: 'typescript',
},
externalHelpers: true,
transform: {
react: {
runtime: 'automatic',
},
},
},
},
},
},
{
test: Repack.getAssetExtensionsRegExp(Repack.ASSET_EXTENSIONS),
use: {
loader: '@callstack/repack/assets-loader',
options: {
platform,
devServerEnabled: Boolean(devServer),
},
},
},
],
},
plugins: [
new rspack.IgnorePlugin({ resourceRegExp: /@react-native-masked-view/ }),
/**
* Configure other required and additional plugins to make the bundle
* work in React Native and provide good development experience with
* sensible defaults.
*
* `Repack.RepackPlugin` provides some degree of customization, but if you
* need more control, you can replace `Repack.RepackPlugin` with plugins
* from `Repack.plugins`.
*/
new Repack.RepackPlugin({
context,
mode,
platform,
devServer,
output: {
bundleFilename,
sourceMapFilename,
assetsPath,
},
}),
new Repack.plugins.ModuleFederationPlugin({
name: 'host',
shared: {
react: {
...Repack.Federated.SHARED_REACT,
requiredVersion: '18.2.0',
eager: true,
},
'react-native': {
...Repack.Federated.SHARED_REACT_NATIVE,
requiredVersion: '0.74',
eager: true,
},
reselect: {
singleton: true,
requiredVersion: monorepoDeps['reselect'],
eager: true,
},
'react-redux': {
singleton: true,
requiredVersion: monorepoDeps['react-redux'],
eager: true,
},
'@reduxjs/toolkit': {
singleton: true,
requiredVersion: monorepoDeps['@reduxjs/toolkit'],
eager: true,
},
'@reduxjs/toolkit/query': {
singleton: true,
requiredVersion: monorepoDeps['@reduxjs/toolkit/query'],
eager: true,
},
'@reduxjs/toolkit/query/react': {
singleton: true,
requiredVersion: monorepoDeps['@reduxjs/toolkit/query/react'],
eager: true,
},
'@react-navigation/native': {
singleton: true,
requiredVersion: monorepoDeps['@react-navigation/native'],
eager: true,
},
'@react-navigation/native-stack': {
singleton: true,
requiredVersion: monorepoDeps['@react-navigation/native-stack'],
eager: true,
},
'react-native-screens': {
singleton: true,
requiredVersion: monorepoDeps['react-native-screens'],
eager: true,
},
'react-native-safe-area-context': {
singleton: true,
requiredVersion: monorepoDeps['react-native-safe-area-context'],
eager: true,
},
'redux-persist': {
singleton: true,
requiredVersion: monorepoDeps['redux-persist'],
eager: true,
},
'@react-native-async-storage/async-storage': {
singleton: true,
requiredVersion:
monorepoDeps['@react-native-async-storage/async-storage'],
eager: true,
},
},
}),
new rspack.EnvironmentPlugin({ MF_CACHE: null }),
process.env.RSDOCTOR && new RsdoctorRspackPlugin(),
].filter(Boolean),
};
};
Try to start the dev server using:
react-native webpack-start --webpackConfig ./rspack.config.mjs
Hi @sahajarora1286, could you please create a reproduction repository with this issue? It really saves a lot of time and allows us to handle issues more swiftly instead of trying to recreate this on our own, thanks!
This issue has been marked as stale because it has been inactive for 30 days. Please update this issue or it will be automatically closed in 14 days.
Closing since no repro was provided and the issue is about a non-stable version of Re.Pack. Happy to revisit the issue if it's still a problem in the future.