目前正在工作
使用Webpack 2和React Router v4,我已经能够设置工作代码拆分。有一个中间的<AsyncComponent>
,它解析promise并返回组件(在github问题上找到的模式)。
下面是一组路由示例:
<Switch>
<Route
path="me"
render={(props) =>
<AsyncComponent promise={ require.ensure([], (require) => require('./modules/Profile'), 'profile') } props={props} />
}
/>
<Route
path="credit-card"
render={(props) =>
<AsyncComponent promise={ require.ensure([], (require) => require('./modules/CreditCard'), 'credit-card') } props={props} />
}
/>
</Switch>
目标
我想进一步扩展这一点,对于某些路由,只需要,就可以加载额外的库。在上面的示例中,我只想在信用卡路径上获取StripeJS (https://js.stripe.com/v2/)库。
我想强调的是,我可以直接加载条纹到页脚,一切正常工作。这里有多个库,我把它作为一个易于理解的例子来使用。
已尝试
已经尝试了以下几种方法,但收效甚微:
在webpack配置中标记外部库的
src
属性的<script>
,等待它加载,然后让组件完成它的工作。这个不错,但从可维护性的角度来看(如果需要两个或更多的库,我就需要复制笨拙的手动script
加载),这真的很糟糕,而且似乎与webpack的“方式”相反。配置的相关部分
const core = [
'lodash',
'react',
'react-dom',
'axios',
'react-router-dom',
];
const config = {
context: path.resolve(__dirname, './ts_build'),
node: {
fs: "empty"
},
entry: {
app: './app.js',
core: core,
},
output: {
filename: '[name].js',
chunkFilename: '[name].[id].chunk.js',
path: path.resolve(__dirname, './../../public'),
publicPath: 'http://example.org/',
},
resolve: {
modules: [
path.resolve('./src'),
],
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['core'],
minChunks: Infinity,
}),
new webpack.NamedModulesPlugin(),
],
};
发布于 2017-03-12 02:09:06
https://github.com/hinok/webpack2-react-router-code-splitting
存储库包含使用动态import()的webpack2
+ react-router v4
+实现的code splitting
,并且只使用loadjs按需加载一次外部库。例如,它加载特定路由的Stripe.js
。
在存储库中,您可以找到两种方法来进行代码拆分
它是基于官方的Webpack文档和安德鲁·克拉克的要点
在准备该存储库时,我发现@Chris只想为外部CDN上托管的某些路由加载Stripe.js
。
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['b'], function (b) {
return (root.amdWebGlobal = factory(b));
});
} else {
root.amdWebGlobal = factory(root.b);
}
}(this, function (b) {
return {};
}));
我可以说,UMD包装器是一种标准,但有时人们更喜欢不那么固执己见的包装器,或者他们只是不关心其他环境。我提到它是因为在git的历史中,你可以找到commit called Amdify,它更多地证明了如何模拟AMD环境的概念。最后,我决定删除它,因为它远不是理想的,它没有涵盖所有的用法和边缘情况。
我找不到任何关于集成外部AMD模块或以某种方式使用AMD模块的信息。相反,我发现它根本不能工作。
AMD @mc-zone你应该能够用script.js加载
模块。但这与webpack无关,它之所以有效,是因为AMD就是为此而设计的。因此,您将无法使用这些AMD模块中的webpack功能。webpack要求对构建时间进行静态分析。
作者:@jhns see on github
的webpack并不处理脚本加载。为此,请使用单独的库。即https://github.com/ded/script.js/
作者:@sokra see on github
如果不可能,则不应该使用
(),而是通过像script.js这样的脚本加载器加载它。
作者:@jhns see on github
关于Github的相关问题:
今天我在medium上找到了an article by James Kale关于他的项目react-loadable的信息,这个项目与LazilyLoad
组件的功能几乎相同,但承诺
我强烈建议你去看看。
发布于 2017-02-14 12:58:57
如果您使用的是Webpack 2,请在React路由器配置文件中使用import()
export default {
component: App,
childRoutes: [
{
path: '/',
getComponent(location, cb) {
import('external-library-here')
.then(function(){
return System.import('pages/Home');
})
.then(loadRoute(cb)).catch(errorLoading);
}
},
{
path: 'blog',
getComponent(location, cb) {
import('pages/Blog').then(loadRoute(cb)).catch(errorLoading);
}
},
{
path: 'about',
getComponent(location, cb) {
import('pages/About').then(loadRoute(cb)).catch(errorLoading);
}
},
]
};
您还可以使用Router
组件中的getComponent
或getComponents
属性来传入专门用于该路由的模块。
发布于 2017-02-23 10:20:24
这个问题中有一些情况应该详细考虑。
让我们开始吧。
观察
react-router
的使用从components改为PlainRoute
object,这将使您在进行代码拆分时具有更大的灵活性,并且还可以跳过创建<AsyncComponent>
component credit-card
路由中的嵌套组件需要库怎么办?< code >F29
建议
。
这是一个尚未实施的建议,但我正在尝试将您的问题引向正确的方向
最后,这是我建议的方法:
import App from 'components/App';
function errorLoading(err) {
console.error('Dynamic page loading failed', err);
}
function loadRoute(cb) {
return (module) => cb(null, module.default);
}
function injectLibraries(libraries) {
Object.keys(libraries).forEach(key => {
window[key] = libraries[key];
});
}
export default {
component: App,
childRoutes: [
{
path: '/(index.html)',
name: 'home',
getComponent(location, cb) {
const importModules = Promise.all([
import('components/HomePage/'),
import('components/HomePage/libraries'),
]);
const renderRoute = loadRoute(cb);
importModules.then(([component, libraries]) => {
injectLibraries(libraries);
renderRoute(component);
});
importModules.catch(errorLoading);
},
},
{
path: '/credit-card',
name: 'credit-card',
getComponent(nextState, cb) {
const importModules = Promise.all([
import('components/CreditCardPage/'),
import('components/CreditCardPage/libraries'),
]);
const renderRoute = loadRoute(cb);
importModules.then(([component, libraries]) => {
injectLibraries(libraries);
renderRoute(component);
});
importModules.catch(errorLoading);
},
},
],
};
您的库文件应如下所示:
import stripe from 'stripe';
export default {
stripe
};
https://stackoverflow.com/questions/42207159
复制相似问题