Webpack 3+React 16コード分割の実現
プロジェクトの背景
最近のプロジェクトにはwebpackのバージョンが古いプロジェクトがあります。アップグレードとフレーム交換のため、しばらくはleader層に受け入れられません。o(ini)oは既存の条件でしか最適化できません。
明らかに項目の構成はv 1から継承されています。v 1->v 3のアップグレードは簡単です。公式サイトhttps://webpack.js.org/migrate/3/を参照すればいいです。
loadersはrulesになります
チェーンの書き方をサポートしないloaderは、json-loaderは配置が不要です。
UglifyJs Pluginプラグインは自分でminimizeを開く必要があります。
既存のカバンの問題を分析する
webpack-bundle-analzerを使ってパッケージを構築した後、図のように
問題は非常に明らかである:
zxcvbnという大きなカバンが取り外された以外に、コードはベンダーとapのために簡単に包装されています。ファイルは大きいです。
ダイナミックimport分割ベンダー
ベンダーのコードを分析して、いくつかの大きなカバン、例えばlibphonenumber.js、使うシーンはそんなに頻繁ではありません。
react公式コード分割ガイドを参照してください。https://react.docschina.org/docs/code-splitting.html#import
修正後の効果:
libphonenumber.js(1.chunnk.js)はベンダーから切り離され、プロジェクトの実際の実行中に、usePhone NumberUtilフローに入る時だけ、libphonumber.jsファイルをサーバに要求します。
ルートによるコード分割
React.lazy
react公式コード分割ガイド-ルートベースコード分割https://react.docschina.org/docs/code-splitting.html#route-based-code-spliting。
分割前の例:
app.jsはルートによってwebpackによって自動的に異なるファイルに分割され、ルートが切り替わると、目的のルートコードファイルが引っ張られます。
名前付きエクスポート
この部分はhttps://react.docschina.org/docs/code-splitting.html#named-exportsから引用される。
React.lazy小包の不精なロードルートコンポーネントは、Suspenseを追加する必要があります。強制的に使用したくない場合、または自由拡張lazyの実現が必要であれば、AyncComponentを実現することが定義され、使用方法はlazyと同じです。
ルートベースのコード分割が完了したら、パッケージのサイズをよく見てみると、全体のサイズが逆に大きくなり、2.5 Mは3.5 Mに増加します。
webpack分析ツールから見ると、張本人は個々のルートコードの中でcomponents、utils、locarsのような公共文書を個別に包装しています。
webapckの配置を使って、comonの部分を個別に包装して解決します。
componentsファイル統合エクスポート
例はcomponentsの下のすべてのファイルを一緒にエクスポートし、他のファイルは同じです。
commonを抽出した後のコード
各ルートの重複したコードを抽出すると、パケットの総サイズはまた2.5 Mになる。commonのbundleファイルが一つ増えました。commonが大きすぎて、実際には分解し続けることができます)
締め括りをつける
webpackパッケージはまだ最適化できるところがたくさんあります。また、webpackバージョンの間にも違いがあります。
ここでWebpack 3+React 16コード分割の実現に関する記事を紹介します。もっと関連するWebpack 3+React 16コード分割の内容は以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。
最近のプロジェクトにはwebpackのバージョンが古いプロジェクトがあります。アップグレードとフレーム交換のため、しばらくはleader層に受け入れられません。o(ini)oは既存の条件でしか最適化できません。
webpack3 + react16
webpack v 3配置検査明らかに項目の構成はv 1から継承されています。v 1->v 3のアップグレードは簡単です。公式サイトhttps://webpack.js.org/migrate/3/を参照すればいいです。
loadersはrulesになります
チェーンの書き方をサポートしないloaderは、json-loaderは配置が不要です。
UglifyJs Pluginプラグインは自分でminimizeを開く必要があります。
既存のカバンの問題を分析する
webpack-bundle-analzerを使ってパッケージを構築した後、図のように
問題は非常に明らかである:
zxcvbnという大きなカバンが取り外された以外に、コードはベンダーとapのために簡単に包装されています。ファイルは大きいです。
ダイナミックimport分割ベンダー
ベンダーのコードを分析して、いくつかの大きなカバン、例えばlibphonenumber.js、使うシーンはそんなに頻繁ではありません。
react公式コード分割ガイドを参照してください。https://react.docschina.org/docs/code-splitting.html#import
import { PhoneNumberUtil } from 'google-libphonenumber'
function usePhoneNumberUtil(){
// PhoneNumberUtil
}
動的import()
方式に変更しました。thenとasync/awaitは非同期データを取得するためにサポートされています。
const LibphonenumberModule = () => import('google-libphonenumber')
function usePhoneNumberUtil(){
LibphonenumberModule().then({PhoneNumberUtil} => {
// PhoneNumberUtil
})
}
Webpackがこの文法を解析すると、自動的にコード分割が行われます。修正後の効果:
libphonenumber.js(1.chunnk.js)はベンダーから切り離され、プロジェクトの実際の実行中に、usePhone NumberUtilフローに入る時だけ、libphonumber.jsファイルをサーバに要求します。
ルートによるコード分割
React.lazy
react公式コード分割ガイド-ルートベースコード分割https://react.docschina.org/docs/code-splitting.html#route-based-code-spliting。
分割前の例:
import React from 'react';
import { Route, Switch } from 'react-router-dom';
const Home = import('./routes/Home');
const About = import('./routes/About');
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Suspense>
</Router>
);
分割後の例:
import React, { lazy } from 'react';
import { Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
//
)
分割後の効果:app.jsはルートによってwebpackによって自動的に異なるファイルに分割され、ルートが切り替わると、目的のルートコードファイルが引っ張られます。
名前付きエクスポート
この部分はhttps://react.docschina.org/docs/code-splitting.html#named-exportsから引用される。
React.lazy
は現在、デフォルトのエクスポートのみをサポートしています。導入したいモジュールがネーミング導出を使用すると、中間モジュールを作成して、デフォルトモジュールとして再エクスポートできます。これはtree sharkingが間違いなく、不要な部品を導入する必要がないことを保証します。
// ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;
// MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";
// MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));
自分でAyncComponentを実現します。React.lazy小包の不精なロードルートコンポーネントは、Suspenseを追加する必要があります。強制的に使用したくない場合、または自由拡張lazyの実現が必要であれば、AyncComponentを実現することが定義され、使用方法はlazyと同じです。
import AsyncComponent from './components/asyncComponent.js'
const Home = AsyncComponent(() => import('./routes/Home'));
const About = AsyncComponent(() => import('./routes/About'));
// async load component
function AsyncComponent(getComponent) {
return class AsyncComponent extends React.Component {
static Component = null
state = { Component: AsyncComponent.Component }
componentDidMount() {
if (!this.state.Component) {
getComponent().then(({ default: Component }) => {
AsyncComponent.Component = Component
this.setState({ Component })
})
}
}
// component will be unmount
componentWillUnmount() {
// rewrite setState function, return nothing
this.setState = () => {
return
}
}
render() {
const { Component } = this.state
if (Component) {
return <Component {...this.props} />
}
return null
}
}
}
common業務コードの分離ルートベースのコード分割が完了したら、パッケージのサイズをよく見てみると、全体のサイズが逆に大きくなり、2.5 Mは3.5 Mに増加します。
webpack分析ツールから見ると、張本人は個々のルートコードの中でcomponents、utils、locarsのような公共文書を個別に包装しています。
webapckの配置を使って、comonの部分を個別に包装して解決します。
componentsファイル統合エクスポート
例はcomponentsの下のすべてのファイルを一緒にエクスポートし、他のファイルは同じです。
function readFileList(dir, filesList = []) {
const files = fs.readdirSync(dir)
files.forEach((item) => {
let fullPath = path.join(dir, item)
const stat = fs.statSync(fullPath)
if (stat.isDirectory()) {
//
readFileList(path.join(dir, item), filesList)
} else {
/\.js$/.test(fullPath) && filesList.push(fullPath)
}
})
return filesList
}
exports.commonPaths = readFileList(path.join(__dirname, '../src/components'), [])
webpack配置はcomonから外れます。
import conf from '**';
module.exports = {
entry: {
common: conf.commonPaths,
index: ['babel-polyfill', `./${conf.index}`],
},
... //
plugins:[
new webpack.optimize.CommonsChunkPlugin('common'),
... // other plugins
]
}
webpack 3では、Commons ChunkPluginを使用して、第三者ライブラリと共通モジュールを抽出し、着信パラメータcommon
は、entrtyが既に存在しているchunkであると、このchunkに共通モジュールコードを統合する。commonを抽出した後のコード
各ルートの重複したコードを抽出すると、パケットの総サイズはまた2.5 Mになる。commonのbundleファイルが一つ増えました。commonが大きすぎて、実際には分解し続けることができます)
締め括りをつける
webpackパッケージはまだ最適化できるところがたくさんあります。また、webpackバージョンの間にも違いがあります。
ここでWebpack 3+React 16コード分割の実現に関する記事を紹介します。もっと関連するWebpack 3+React 16コード分割の内容は以前の文章を検索してください。または下記の関連記事を引き続きご覧ください。これからもよろしくお願いします。