Webpack之按需加載

Webpack之按需加載

若是系統很龐大,將代碼一次性載入,就顯得太過於強大,最好能作到根據咱們的需求來選擇性地加載咱們須要的代碼。node

本文的原文在個人博客中:github.com/RachelRen/b…,歡迎star。react

webpack 提供了2種方式來拆分代碼。webpack

  1. 符合 ECMAScript 提案 的 import() 語法 來實現動態導入。(import() 調用會在內部用到 promises。)
  2. 則是 webpack 的遺留功能,使用 webpack 特定的 require.ensure
import(/* webpackChunkName: "b" */ './b').then(function(module){
    const b = module.default;
    b();
})
複製代碼

如今都比較推薦第一種方式,從實踐中能夠獲得下面的結論git

  1. webpack中output的設置並不決定是否拆分代碼
  2. 拆分代碼的決定因素在import語法上
  3. webpack在掃描到代碼中有import語法的時候,才決定執行拆分代碼

在業務中,若是使用的是react,通常都是須要和react-router聯合使用的。github

那麼通常配置以下,web

步驟一

webpack.config.jspromise

var path = require('path');
var webpack = require('webpack');
module.exports = {
  entry:'./a.js',
  mode:'development',
  output:{
    filename:'[name].js',
    chunkFilename:'[name].js',// 設置按需加載後的chunk名字
    publicPath:'dist/'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
        }
      }
    ]
  },
  devServer: {
    contentBase: './',
    compress: true,
    port: 9000,
    hot: true,
  },
  plugins: [
      new webpack.NamedModulesPlugin(),
      new webpack.HotModuleReplacementPlugin()
  ],
}

複製代碼

步驟二: 添加.babelrc

{
  "presets": ["@babel/preset-react","@babel/preset-env"],
  "plugins": ["@babel/plugin-syntax-dynamic-import"]
}

複製代碼

步驟三:書寫jsx

import React,{Component} from 'react';
import ReactDom from 'react-dom';

export default class A extends Component{
  render(){
    return <div>
      this is A
    </div>
  }
}
ReactDom.render(<A />,document.getElementById('component'))

複製代碼

步驟四: 集成react-loadable

如今用react-loadable方式實現的按需加載是官方比較推薦的方式。 在這個過程當中,用了import()這個方法bash

import React,{Component} from 'react';
import { BrowserRouter as Router, Route, Switch,Link } from 'react-router-dom';
import ReactDom from 'react-dom';
import Loadable from 'react-loadable';

const Loading = () => <div>Loading...</div>;

const B = Loadable({
  loader: () => import('./b.js'),
  loading: Loading,
})
const C = Loadable({
  loader: () => import('./C.js'),
  loading: Loading,
})
export default class A extends Component{
  render(){
    return <div>
      <Router>
        <div>
          <Route path="/B" component={B}/>
          <Route path="/C" component={C}/>
          <Link to="/B">to B</Link><br/>
          <Link to="/C">to C</Link>
        </div>
      </Router>
    </div>
  }
}
ReactDom.render(<A/>,document.getElementById('component'))

複製代碼

步驟五:封裝Loadable組件

const LazyLoad = (path)=>{
  return Loadable({
    loader: () => import(path),
    loading: Loading,
  })
}

const B = LazyLoad('./b.js')
複製代碼

若是用上面的方式來封裝組件,會發現報錯。由於webpack編譯的時候,會先掃描一遍js文件,找出須要按需加載的部分,而後進行按需加載,不會關心內部的js執行上下文。babel

因此只能把import的部分拿出來。react-router

const LazyLoad = loader => Loadable({
  loader,
  loading:Loading,
})
const B = LazyLoad(()=>import('./b.js'));

複製代碼

項目代碼

github.com/RachelRen/d…

相關文章
相關標籤/搜索