I am publishing a module that uses a few peer dependencies:
In my package.json file i declare peerDependencies:
...
"peerDependencies": {
"react": ">=16",
"react-dom": ">=16",
"@material-ui/core": ">=4",
"@material-ui/icons": ">=4"
},
...
And in my webpack config I declare externals along with an output format of commonjs2
(I'm not at all sure why I would use commonjs2
instead of commonjs
):
...
output: {
filename: 'index.js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, output),
},
externals: {
react: 'react',
'react-dom': 'react-dom',
'@material-ui/core': '@material-ui/core',
'@material-ui/icons': '@material-ui/icons',
},
...
That seems to be working in that I can see the externals are NOT included in the output file. However, including the output of this package in my project results in a MUCH larger bundle size.
I think it's because the output of the bundle converts my import
statements to require
statements, so that in my project where I'm using this package the peer dependencies defined as require
statements can't be optimized.
In other words, the output of the package, instead of including the @material-ui/core
library as part of the build, will instead reference it as require('@material-ui/core')
Is that correct?
What is the correct way to package peer dependencies so that:
I THINK (but could be wrong) that what is happening at the moment is that:
// In my project where I consume the package
import { Thing } from '@org/package-name'
// And in @org/package-name` source code, I have
import { Card } from '@material-ui/core'
// Which gets transpiled to (more or less)
require('@material-ui/core').Card
// Which means that when I use "Thing", that I'm loading the whole of @material-ui/core
I've also tried configuring babel with babel-plugin-transform-imports
. But I'm finding that I would then have to configure the peer dependencies / externals for every import (@material-ui/core/Card
, @material-ui/core/List
, etc. etc.)
The working solution, I have found, is to set targets.esmodules to true in the babel configuration for preset-env.
I think that the reason this worked for me is that I was re-exporting modules in a single entry. And the named exports in the commonjs format can't easily be isolated on import?
But that's just a guess.