我试图用webpack设置我的项目,我已经读过有关代码分裂的内容,我正在尝试创建两个独立的bundle,一个用于实际的应用程序代码,另一个用于库和框架。所以我的webpack配置看起来像这样:
entry: {
app: './app/index.js',
vendor: './app/vendor.js'
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'public/js')
},
watch: true,
module: {
rules: [{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: 'css-loader'
})
}]
},
plugins: [
new ExtractTextPlugin('styles.css'),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
})
]
在我的vendor.js包中我只有一行:
import moment from 'moment';
当我尝试在我的app.js文件中使用它时,它告诉我,那个时刻没有定义。那么,我不能得到的东西,捆绑是否有共同的范围?如果没有,那么我如何访问我已经在另一个捆绑中导出的变量,如果我不能,那么即使是像这里描述的那样拥有供应商捆绑包的重点https://webpack.js.org/guides/code-splitting-libraries/ ?
答案 0 :(得分:6)
捆绑包不共享范围。实际上webpack尊重每个模块的范围,就像Node.js一样,所以你不能使用其他模块中的任何东西,除非你导入它,即使它在同一个包中。
您需要在每个使用它的模块中导入Public class Tab2Vid extand Fragment implement View.OnClickListener {
Public View onCreateView(LayoutInflater inflater, ViewGroup container
,Bundle savedlnstanceState) {
View rootView = inflater.inflate(R.layout.tab2video, container, false);
Button play = (Button)rootView.findViewById(R.id.btnplay);
return rootView;
}
Public void onClick(View view)(
switch (view.getId())
{
case R.id.btnplay:
Toast.makeText(getActivity(),"Btn Play clicked", Toast.LENGTH_SHORT).show();
break;
default:
return;
}
}
}
。这并不意味着您多次包含其源代码。 Webpack包含一次源代码,每次导入都会引用它。
代码拆分,在这种情况下为moment
,只是将源放入供应商捆绑包中,并且捆绑包中的每个导入都将引用供应商捆绑包。这意味着您不会将供应商依赖项与您的应用程序包一起发布,因此浏览器可以缓存供应商捆绑包。当您在不更改供应商捆绑包的情况下发布应用程序的新版本时,浏览器只需要下载应用程序包,因为它已经拥有正确的供应商捆绑包。
让我们考虑一下这个非常简短的示例应用程序:
CommonsChunkPlugin
如果没有import moment from 'moment';
console.log(moment().format());
生成的包(不是uglified),则为:
CommonsChunkPlugin
那是470 KB,因为它包含了捆绑包中的整个vendor.js 470 kB 0 [emitted] [big] vendor
app.js 470 kB 1 [emitted] [big] app
来源,更糟糕的是,另一个也使用moment
的捆绑包也包含整个源代码。供应商不应该在这里使用它,但想到另一个需要使用它的捆绑包。当您在应用程序中更改某些内容时,用户必须再次下载整个470 KB。
使用moment
:
CommonsChunkPlugin
现在应用程序下降到504字节。当您更改应用程序时,用户只需下载此小包(假设 app.js 504 bytes 0 [emitted] app
vendor.js 473 kB 1 [emitted] [big] vendor
已被缓存)。这也意味着使用vendor.js
的任何其他捆绑包也会引用moment
,而不是在捆绑包中包含源。
vendor.js
的大小略有增加,因为webpack需要一些额外的代码来处理来自另一个bundle的导入。这还需要在vendor.js
之前加载vendor.js
。
为了简洁起见,我省略了文件名中的哈希值,但是它们是缓存清除所必需的。有关详细信息,请参阅Caching。
答案 1 :(得分:3)
我看到了问题,但它与代码拆分无关。根据具体情况,有不同的方法可以实现这一目标:
vendor.js
中需要index.js
:vendor.js
export default moment from 'moment';
index.js
var moment = require('vendor.js');
console.log(moment());
导入加载器允许您使用依赖于特定全局变量的模块。这对于依赖全局变量(如$或这是窗口对象)的第三方模块非常有用。导入加载程序可以添加必要的需求('无论什么')调用,因此这些模块可以与webpack一起使用。
require("imports-loader?$=moment,angular!./index.js");
您可以通过插件将momentJS暴露给windows对象,因此您可以从index.js访问window.moment
。
new webpack.ProvidePlugin({
"window.moment": "moment"
}),
答案 2 :(得分:0)
所以我一直在努力将一个对象及其所有方法从一个单独的.js
文件导入到app.js
,同时使用webpack
。事实证明,你所要做的就是....
假设您在var xys{};
ourjsfile.js
个对象
你已经定义了各种方法,比如..
xyz.add = function(){ ... };
在文件的末尾,您只需添加..
module.exports = xyz;
多数民众赞成!现在,为了在app.js
中使用此对象(变量),您必须按以下要求...
var xyz = require('./ourjsfile');
瞧瞧!!!该对象已导入。对于这样一个简单的解决方案,这件事让我的头发拉得太久了。