先说说已有的几种模块加载方式
script
最原始的js文件加载方式,把每个文件作为一个模块
<script src='a.js'></script> <script src='b.js'></script>
commonJS
用require方法同步加载依赖的模块,通过exports或module.exports导出要暴露的接口
var a = require('a.js'); a.doSomething(); ... module.exports = b;
AMD
异步加载模块,声明模块的时候指定依赖,即依赖前置
define(['a'], function(a) { a.doSomething(); ... return b; })
ES6
es6标准新增了import和export,原生浏览器端还没有实现此标准,因此需要通过babel来实现
import a from 'a';
a.doSomething();
...
export b;
webpack
module.exports = { entry: { './public/scripts/bundle': './src/index.js' }, output: { path: __dirname, publicPath: '/', filename: '[name].js' //name对应entry里的key值 }, resolve: { extensions: ['', '.js', '.jsx'] }, module: { //webpack本身只能处理原生js模块,loader可以将各种类型资源转换为js模块供webpack处理 loaders: [ { test: /.jsx?$/, loader: 'babel', query: { presets: ['es2015', 'react', 'stage-2'] }, exclude: /node_modules/ }, { test: /.scss$/, loader: ExtractTextPlugin.extract('css!sass') } ] }, plugins: [ new ExtractTextPlugin('public/styles/bundle.css', {allChunks: true}) ] }
注意到在babel-loader中,指定了一些presets。因为babel 6不会自己加载所有内容,需要我们告诉它要加载哪些模块,es2015对应es6,react对应jsx。而stage系列是对es7一些提案的支持。数字越小则包含的功能越多,如stage-0包含了stage-1,stage-2,stage-3的所有功能加上额外的新功能,以此类推。其中
stage-2支持transform-object-rest-spread,es6只支持数组的解构,而加上这个插件便可扩展到对象上,在redux中非常好用
stage-3支持transform-async-to-generator,主要用来支持async和await
既然各类型资源都可以看作模块来加载,各模块可以在js中通过require('mycssfile.css')来加载各自对应的css文件,然后style-loader将在head标签下创建style添加这些css内容。这样做的一个问题,就是可能会产生过多的style标签,我们可以使用ExtractTextPlugin插件将css全部抽离出来放到一个output里
webpack还能实现强大的按需加载,解决因打包文件体积过大导致初始化很慢的问题。以后用到再更新