複数のreactコンポーネントのライブラリがあり、ライブラリをツリーシェイク可能にして、次のようなコンポーネントをインポートするときに
import { Checkbox } from 'my-react-components'
バンドル全体をインポートしません。
私のindex.jsは次のようになります
export { default as Button } from './components/Button'
export { default as Checkbox } from './components/Checkbox'
export { default as FlexView } from './components/FlexView'
export { default as Radio } from './components/Radio'
export { default as Select } from './components/Select'
export { default as TextInput } from './components/TextInput'
export { default as Toggle } from './components/Toggle'
そして、webpackを使用してバンドルします
module.exports = {
mode: 'production',
entry: './src/index.ts',
output: {
path: path.resolve('./lib'),
filename: 'react-components.js',
libraryTarget: 'commonjs2',
},
// loaders and stuff...
// terser-webpack-plugin...
externals: {
// don't include react in the bundle
react: {
root: 'React',
commonjs2: 'react',
commonjs: 'react',
AMD: 'react',
},
},
optimization: {
splitChunks: false,
sideEffects: false,
},
}
そしてもちろん私のbabel設定には
['@babel/preset-env', {
modules: false,
}]
この設定では、コンポーネントを1つだけインポートすると、バンドル全体が含まれます(インポートするときもwebpackを使用しています)。どうすればこれを防ぐことができますか?
package.json
にmodule
プロパティも必要だと思います
{
...
"main": "lib/index.js",
"module": "lib/index.esm.js",
...
}
ライブラリに名前を付けるだけでなく、ライブラリのlibフォルダーからファイルを直接インポートすることで、これを機能させることができました。
私の場合、次のようにReactstrapライブラリからいくつかのコンポーネントをインポートしました。
import Button from 'reactstrap/lib/Button';
import UncontrolledPopover from 'reactstrap/lib/UncontrolledPopover';
import PopoverHeader from 'reactstrap/lib/PopoverHeader';
import PopoverBody from 'reactstrap/lib/PopoverBody';
指定したルールに従ってインポートを変換するのに役立つ効果的な babelプラグイン があります。
[
'transform-imports', // or 'babel-plugin-transform-imports'
{
'react-router': {
transform: 'react-router-dom/${member}',
preventFullImport: true
},
reactstrap: {
transform: 'reactstrap/lib/${member}',
preventFullImport: true
}
}
]
注:preventFullImport
は、そのパスへのインポートがツリーシェイク可能であることを確認する場合に役立ちます。
これは、未使用のインポートを効果的にツリーシェイクするのに役立つ実装のもう1つの方法です。ただし、長期的には、ファイルごとに直接インポートすることがベストプラクティスになります。
import Button from 'reactstrap/lib/Button';
import UncontrolledPopover from 'reactstrap/lib/UncontrolledPopover';
2020年2月現在、Webpackでは使用できません。
ツリーシェーキングメカニズムはES6import/export
に大きく依存しており、Webpackは現在output.libraryTarget
のES2015モジュール形式をサポートしていないためです。
別の方法として、ライブラリをRollup(ライブラリのES6モジュールをサポートする)などの他のバンドラーとバンドルすることもできます。
この機能はここで追跡できます: https://github.com/webpack/webpack/issues/29
[〜#〜] update [〜#〜]:ハッキーな回避策がありますが: https://stackoverflow.com/a/ 60010871/92119