Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack的按需加载 #28

Open
RachelRen opened this issue May 21, 2019 · 0 comments
Open

webpack的按需加载 #28

RachelRen opened this issue May 21, 2019 · 0 comments

Comments

@RachelRen
Copy link
Owner

按需加载

如果系统很庞大,将代码一次性载入,就显得太过于强大,最好能做到根据我们的需求来选择性地加载我们需要的代码。

webpack 提供了2种方式来拆分代码。

  1. 符合 ECMAScript 提案 的 import() 语法 来实现动态导入。(import() 调用会在内部用到 promises。)
  2. 则是 webpack 的遗留功能,使用 webpack 特定的 require.ensure
import(/* webpackChunkName: "b" */ './b').then(function(module){
    const b = module.default;
    b();
})

现在都比较推荐第一种方式,从实践中可以得到下面的结论

  1. webpack中output的设置并不决定是否拆分代码
  2. 拆分代码的决定因素在import语法上
  3. webpack在扫描到代码中有import语法的时候,才决定执行拆分代码

在业务中,如果使用的是react,一般都是需要和react-router联合使用的。

那么一般配置如下,

步骤一

webpack.config.js

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"]
}

步骤三:书写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 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执行上下文。

所以只能把import的部分拿出来。

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

脑阔疼的webpack按需加载

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant