-
-
Notifications
You must be signed in to change notification settings - Fork 781
Description
System Info
System:
OS: macOS 14.6.1
CPU: (10) arm64 Apple M2 Pro
Memory: 174.80 MB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.16.0 - ~/.nvm/versions/node/v20.16.0/bin/node
npm: 10.8.1 - ~/.nvm/versions/node/v20.16.0/bin/npm
pnpm: 9.7.1 - ~/Library/pnpm/pnpm
Browsers:
Chrome: 130.0.6723.70
Safari: 17.6
npmPackages:
@rspack/cli: ^1.0.14 => 1.0.14
@rspack/core: ^1.0.14 => 1.0.14
Details
When compiling to a library with type 'umd' and using externals, Rspack will error out if you forgot to add the 'root' | 'commonjs' | 'commonjs2' properties to one of your externals.
for example:
Good ✅
export default {
output: { library: { type: "umd" } },
externals: {
react: {
commonjs: "react",
commonjs2: "react",
root: "React"
}
}
}Bad ❌
export default {
output: { library: { type: "umd" } },
externals: {
react: {
commonjs: "react",
commonjs2: "react" // Notice no 'root' property. But removing any of these three will result in an error.
}
}
}This makes sense as critical information is missing for Rspack to be able to construct a correct UMD import of the react library.
The bad example will throw the following error:
[rspack-cli] [Error: × Missing external configuration for type: root
] {
code: 'GenericFailure'
}
How Webpack treats this
When you do this in webpack - webpack compiles successfully without any error. but the resulting code has errors in it.
So i think Rspack actually does the right thing here but fails to communicate this properly.
for example if you had this code:
import React from 'react'
console.log(React)webpack would output something like this:
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("react"));
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
// 🚧 notice the root[undefined] here which should have been root['React']
// but because webpack doesn't have a 'root' property it just puts in undefined.
// This will throw in production👇🏻
var a = typeof exports === 'object' ? factory(require("react")) : factory(root[undefined]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}My Conclusion
I think Rspack does the right thing here I think that there's still some stuff missing in communication and DevX areas:
- The error that Rspack returns is quite vague and general. would be better to say what specific external is missing what properties.
- The types are too general (
Record<string, string | string[]>) and don't let typescript users know that they are defining this configuration wrong. Would be better if when the library type isumdthere was an actual interface that would let users know what properties should be required there (commonjs,commonjs2,amd&root). - Documentation around externals doesn't enumerate the possible values and which are required in which case. https://rspack.dev/config/externals
Reproduce link
https://github.com/ItamarGronich/rspack-externals
Reproduce Steps
- clone the repo
- run
nvm use - run
npm ci - run
npm run test:rspackto see the error printed out - run
npm run test:webpackto see no error printed out