简体   繁体   English

使用webpack,bundle-loader react-router进行隐式代码分割

[英]Implicitly code-splitting with webpack, bundle-loader react-router

Edit2: Edited the regex to match window's file paths and the code splitting is now happening. 编辑2 编辑正则表达式以匹配窗口的文件路径,现在正在进行代码拆分。 But my children components to my root route still won't load. 但我的子路径的子组件仍然无法加载。

Edit: My code has changed since last week, but I'm still stuck on that problem (and I need to declare my routes in a declarative way, so using JSX). 编辑:我的代码自上周以来发生了变化,但我仍然坚持这个问题(我需要以声明的方式声明我的路由,所以使用JSX)。

First of all, I'm using Webpack 1.x with React, react-router, bundle-loader, Babel6, ES6 and airbnb-eslint-config. 首先,我正在使用Webpack 1.x与React,react-router,bundle-loader,Babel6,ES6和airbnb-eslint-config。

I tried following Henley Edition's article about code-splitting and loading chunks (with its example repo ), based on React's huge app example . 我试着根据React的庞大应用程序示例关注Henley Edition关于代码分割和加载块(以及它的示例repo的文章

But I couldn't manage to make bundle-loader split my code into chunks... 但是我无法让bundle-loader将我的代码拆分成块...

Here's my code : 这是我的代码:

webpack.config.js webpack.config.js

const webpack = require('webpack');
const path = require('path');

const nodeDir = `${__dirname}/node_modules`;

const routeComponentRegex = /src[\/\\]views[\/\\]([^\/\\]+)[\/\\]js[\/\\]([^\/\\]+).js$/;
const paths = [ // Only to test which files match the regex, juste in case
  'src/views/index/js/Index.js',
  'src/views/login-page/js/LoginForm.js',
  'src/common/main-content/js/MainContent.js',
  'src/routes/main.js',
];

console.log(routeComponentRegex.test(paths[0])); // prints 'true'
console.log(routeComponentRegex.test(paths[1])); // prints 'true'
console.log(routeComponentRegex.test(paths[2])); // prints 'false'
console.log(routeComponentRegex.test(paths[3])); // prints 'false'

const config = {
  resolve: {
    alias: {
      react: `${nodeDir}/react`,
      'react-dom': `${nodeDir}/react-dom`,
      'react-router': `${nodeDir}/react-router`,
      'react-fetch': `${nodeDir}/react-fetch`,
      'react-cookie': `${nodeDir}/react-cookie`,
      'react-bootstrap': `${nodeDir}/react-bootstrap`,
      'react-bootstrap-daterangepicker': `${nodeDir}/react-bootstrap-daterangepicker`,
      'react-bootstrap-datetimepicker': `${nodeDir}/react-bootstrap-datetimepicker`,
      velocity: `${nodeDir}/velocity-animate`,
      moment: `${nodeDir}/moment`,
      slimscroll: `${nodeDir}/slimscroll`,
    },
  },
  entry: {
    app: './client/src/routes/js/main',
    vendors: [
      'react', 'react-dom',
      'react-router', 'react-fetch', 'react-cookie',
      'react-bootstrap', 'react-bootstrap-daterangepicker', 'react-bootstrap-datetimepicker',
      'velocity', 'moment', 'slimscroll',
    ],
  },
  output: {
    path: path.join(__dirname, 'public/dist'),
    publicPath: '/dist/',
    filename: 'bundles/[name].bundle.js',
    chunkFilename: 'chunks/[name].chunk.js',
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        include: path.join(__dirname, 'client'),
        exclude: routeComponentRegex,
        loader: 'babel',
      },
      {
        test: /\.css$/,
        include: path.join(__dirname, 'client'),
        exclude: routeComponentRegex,
        loader: 'style!css-loader?modules&importLoaders=1' +
        '&localIdentName=[name]__[local]___[hash:base64:5]',
      },
      {
        test: routeComponentRegex,
        include: path.join(__dirname, 'client'),
        loaders: ['bundle?lazy', 'babel'],
      },
    ],
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin('vendors', 'bundles/vendors.js', Infinity),
  ],
};

module.exports = config;

client/src/views/main-content/js/MainContent.js 客户端/ src目录/视图/主要内容/ JS / MainContent.js

import React from 'react';
import { Link } from 'react-router';

const MainContent = (props) => (
    <div>
      <h1>App</h1>
      <ul>
        <li><Link to="/login">Login</Link></li>
      </ul>
      {props.children}
    </div>
);

MainContent.propTypes = {
  children: React.PropTypes.node.isRequired,
};

export default MainContent;

public/src/views/index/js/Index.js 公共/ src目录/视图/索引/ JS / Index.js

import React from 'react';

const Index = () => (
    <h2>Index Page</h2>
);

export default Index;

public/src/views/login/js/Login.js 公共/ src目录/视图/登录/ JS / Login.js

import React from 'react';

const LoginForm = () => (
  <div className="box box-default">
    <h2>Login Page</h2>
  </div>
);

export default LoginForm;

Entry point (client/src/routes/main.js) : 入口点(client / src / routes / main.js):

import React from 'react';
import { render } from 'react-dom';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';

import MainContent from '../../common/main-content/js/MainContent';

// modules supposed to be loaded lazily
import Index from '../../views/index/js/Index';
import Login from '../../views/login/js/Login';
import ShortOffers from '../../views/short-offers/js/ShortOffers';
import CreateJobOffer from '../../views/create-job-offer/js/CreateJobOffer';

function lazyLoadComponent(lazyModule) {
  return (location, cb) => {
    lazyModule(module => {
      cb(null, module);
    });
  };
}

function lazyLoadComponents(lazyModules) {
  return (location, cb) => {
    const moduleKeys = Object.keys(lazyModules);
    const promises = moduleKeys.map(key =>
      new Promise(resolve => lazyModules[key](resolve))
    );

    Promise.all(promises).then(modules => {
      cb(null, modules.reduce((obj, module, i) => {
        obj[moduleKeys[i]] = module;
        return obj;
      }, {}));
    });
  };
}

render((
  <Router history={browserHistory}>
    <Route path="/" component={MainContent}>
      <IndexRoute getComponent={lazyLoadComponent(Index)} />
      <Route path="short-offers" getComponent={lazyLoadComponent(ShortOffers)} />
      <Route path="create-job-offer" getComponent={lazyLoadComponent(CreateJobOffer)} />
    </Route>
    <Route path="login" getComponent={lazyLoadComponent(Login)} />
  </Router>
), document.getElementById('content'));

Now webpack 's output : 现在webpack的输出:

Hash: a885854f956aa8d2a00c
Version: webpack 1.13.0
Time: 6321ms
                Asset     Size  Chunks             Chunk Names
bundles/app.bundle.js  84.7 kB       0  [emitted]  app
   bundles/vendors.js  2.55 MB       1  [emitted]  vendors
chunk    {0} bundles/app.bundle.js (app) 89 kB {1} [rendered]
    [0] multi app 28 bytes {0} [built]
     + 26 hidden modules
chunk    {1} bundles/vendors.js (vendors) 2.45 MB [rendered]
    [0] multi vendors 148 bytes {1} [built]
     + 626 hidden modules

See, no bundles :( If I understood well, the third loader in webpack.config.js should take care of files imported in .js files and make them into chunks , so they could be loaded dynamically (and lazily) . 看,没有捆绑:(如果我理解的话, webpack.config.js的第三个加载器应该处理在.js文件中导入的文件并将它们分成chunks ,这样它们就可以dynamically (and lazily)加载dynamically (and lazily)加载dynamically (and lazily)

Additionally, my pages don't load. 此外,我的页面不加载。 If I take out the code splitting out of the picture, it works : 如果我从图片中取出代码分割,它可以工作:

render((
  <Router history={browserHistory}>
    <Route path="/" component={MainContent}>
      <IndexRoute component={Index} />
      <Route path="short-offers" getComponent={ShortOffers} />
      <Route path="create-job-offer" getComponent={CreateJobOffer} />
    </Route>
    <Route path="login" getComponent={LoginPage} />
  </Router>
), document.getElementById('content'));

But, my app is gonna be huge and I absolutely need code-splitting. 但是,我的应用程序将是巨大的,我绝对需要代码分裂。

Would anyone please have a piece of insight to give me? 有人请有一个洞察力给我?

Thanks in advance! 提前致谢!

Article author here. 文章作者在这里。 Try just running npm start (runs dev server) or webpack -c webpack.config.js (outputs files to __build__ directory). 尝试运行npm start (运行dev服务器)或webpack -c webpack.config.js (将文件输出到__build__目录)。 I think you just forgot to point webpack at the correct config file. 我想你只是忘了将webpack指向正确的配置文件。

use module.exports instead of export default 使用module.exports而不是export default

import React from 'react';
import { Link } from 'react-router';

const MainContent = (props) => (
    <div>
      <h1>App</h1>
      <ul>
        <li><Link to="/login">Login</Link></li>
      </ul>
      {props.children}
    </div>
);

MainContent.propTypes = {
  children: React.PropTypes.node.isRequired,
};

module.exports = MainContent;

or it's better to use babel-plugin-add-module-exports plugin it will transform 或者最好使用babel-plugin-add-module-exports插件进行转换

// index.js 
export default 'foo'

into

'use strict';
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = 'foo';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用webpack和react-router进行延迟加载和代码分割无法加载 - Using webpack and react-router for lazyloading and code-splitting not loading 是否添加.default?:反应路由器3中的动态导入webpack代码拆分 - to add .default or not?: dynamic imports in react router 3 for webpack code-splitting React + React-Router + TypeScript Webpack生产捆绑包问题 - React + react-router + typescript webpack production bundle issue [Webpack] [反应]在具有代码拆分功能的SSR上,如何获取页面所需的块列表? - [Webpack][React] On SSR with code-splitting how I can get the list of chunks needed by the page? 使用Webpack和React-router bundle.js Not Found - Using Webpack with React-router bundle.js Not Found 反应路由器基本代码拆分(获取第一个块,然后在后台异步获取其他块) - React router base code-splitting (get first chunk and then get other chunks async in background) Webpack代码拆分包托管在两个服务器上 - Webpack code-splitting bundles hosted over two servers CSS代码与Webpack 2和React路由器分离 - CSS Code Splitting with Webpack 2 and React Router 使用webpack 1.9反应路由器4 - 路由+代码拆分 - React router 4 - routing + code splitting, with webpack 1.9 使用Ruby On Rails App中的Webpack在ReactJS组件中进行代码拆分 - Code-Splitting in ReactJS Components with Webpack in Ruby On Rails App
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM