I need to publish a single package that can be imported as default (or named as last resort) by multiple projects.
After hundreds of issues trying to do this with Rollup I moved on to trying to bundle my library with Webpack. My package only exports one default.
I have another project that is importing the package as default that I have been testing with, it's intended that it should return the root React component which is default exported.
I have tried bundling with UMD, which doesn't crash my external project but doesn't return an exported default or named export anywhere.
If I set my Webpack config to bundle ESM instead I get an obscure vague error regarding Object.defineProperty.
If somebody has ESM bundling working in Webpack 5 please help, or any ideas that have worked for you
Uncaught TypeError: Object.defineProperty called on non-object
at Function.defineProperty (<anonymous>)
at Function.__webpack_require__.r (build.js:13594)
at eval (index.js:1)
at Object.../discover-v2/dist/index.js (build.js:10623)
at __webpack_require__ (build.js:13402)
at fn (build.js:13671)
at eval (index.tsx:20)
at Module../src/views/Discovers/Discover/index.tsx (build.js:5141)
at __webpack_require__ (build.js:13402)
at fn (build.js:13671)
This points to a webpack function:
/* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
webpack.config.ts:
module.exports = {
entry: './src/package.tsx',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
library: {
// name: 'discover',
type: 'module',
},
libraryTarget: 'module',
module: true,
},
experiments: {
asset: true,
outputModule: true,
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
//TODO waiting on https://github.com/dividab/tsconfig-paths-webpack-plugin/issues/61
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
plugins: [new TsconfigPathsPlugin()],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'babel-loader',
},
{
loader: 'ts-loader',
options: {
transpileOnly: true,
},
},
],
exclude: [/node_modules/, nodeModulesPath],
},
{
test: /\.(png|jpg|mov|mp4)$/,
loader: 'url-loader',
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader'],
},
{
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new webpack.DefinePlugin({
'process.env.LOCAL': JSON.stringify(process.env.LOCAL),
'process.env.STAGING': JSON.stringify(process.env.STAGING),
'process.env.API_URL': JSON.stringify(process.env.API_URL),
'process.env.NODE_ENV': JSON.stringify('production'),
'process.env.NAME': JSON.stringify(pkg.name),
'process.env.VERSION': JSON.stringify(pkg.version),
}),
new ForkTsCheckerWebpackPlugin({
eslint: {
files: './src/**/*.{ts,tsx,js,jsx}', // required - same as command `eslint ./src/**/*.{ts,tsx,js,jsx} --ext .ts,.tsx,.js,.jsx`
},
}),
new CleanWebpackPlugin(),
],
};
.babelrc
{
"presets": [
["@babel/env", { "modules": false }],
"@babel/react",
"@babel/typescript",
[
"@emotion/babel-preset-css-prop",
{
"autoLabel": "always",
"sourceMap": true,
"labelFormat": "[local]"
}
]
],
"plugins": [
"@babel/transform-runtime",
"@babel/proposal-class-properties",
"@babel/proposal-object-rest-spread"
]
}
Root component - src/package.tsx
const RootProvider: React.FC<RootProps> = ({ assets, ...props }) => (
<StoreProvider store={store}>
<ConnectedRouter history={history}>
<AssetsContext.Provider value={assets}>
<Root {...props} />
</AssetsContext.Provider>
</ConnectedRouter>
</StoreProvider>
);
export default RootProvider;
export { RootProvider as discover };
package.json main/module
{
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
...
tsconfig.json
{
"compilerOptions": {
"typeRoots": ["src/@types", "node_modules/@types"],
"sourceMap": true,
"noImplicitAny": false,
"module": "esnext",
"target": "es5",
"lib": ["esnext", "dom", "dom.iterable"],
"removeComments": true,
"allowSyntheticDefaultImports": true,
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
"allowJs": true,
"baseUrl": "./",
"esModuleInterop": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"downlevelIteration": true,
"paths": {
...
},
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"outDir": "dist",
"declarationDir": ".",
"preserveConstEnums": true,
"declaration": true // generates .d.ts files inside the output directory
},
"include": ["./src", "./webpack.config.ts", "./webpack.package.config.ts"],
"exclude": ["dist"]
}
Bundle dist/index.js output exports (added default and named to test)
var __webpack_exports__ = __webpack_require__("./src/package.tsx");
var __webpack_exports__default = __webpack_exports__.default;
var __webpack_exports__discover = __webpack_exports__.discover;
export { __webpack_exports__default as default, __webpack_exports__discover as discover };
My consuming project that is importing the package has a similar webpack (without the library config, including aliases to fix multiple react errors when testing packaged project with yarn link), with an exact same .babelrc and tsconfig.json (with path changes)
alias: {
...
// bypass multiple react versions issue when testing internal packages
react: path.resolve('./node_modules/react'),
'react-dom': path.resolve('./node_modules/react-dom'),
'@emotion/react': path.resolve('./node_modules/@emotion/react'),
'@material-ui/core': path.resolve('./node_modules/@material-ui/core')
}
From my research, it is related to eval-* devtool in webpack config.
https://github.com/webpack/webpack/issues/11277#issuecomment-724024303
A workaround would be to set it (for the project importing that package) to false or change it to something other than eval-* according to docs: https://webpack.js.org/configuration/devtool/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With