省略废话。css
1.ES6以前两个比较流行的模块机制CommonJS和AMD。CommonJS模块就是对象,加载模块时加载的是拷贝;而ES6加载的是对export的变量的引用。vue
2.ES6模块不是对象,使用可出如今模块顶层任何位置的export显式指定输出的代码(变量、函数、class):webpack
export:git
export var name='microsoft'; github
---another example 推荐在底部用{}输出须要的代码web
var value_x='microsoft'; vue-router
export { value_x,value_y ,method_y};vuex
若是想给export的变量更名字,可使用as:api
export { value_x,value_y as alias_name ,method_y};数组
export function fn_name(){};
*export的变量是动态绑定其所在模块的。好比setTimeout后改变value_x的值,接收者获得的value_x也会定时改变。
import:
import { value_x,mothed_y } from strUrl;
value_x,mothed_y的名称必须与 strUr 中export的名称相同。若是想给import的变量更名字,可使用as:
import { value_x as value_z,mothed_y } from strUrl;
*import具备提高效果。
*import会执行所加载的模块。
*import命令中接收的变量名要在{}中
总体加载:
能够用*指定一个对象,全部import的东西都加载到这对象上:
import * as mod from strUrl;
var x=mod.value_x;
也能够用module命令:
module mod from strUrl;
var x=mod.value_x;
export default:
上面说了import命令中加载的变量名称要和export输出的名称一致,咱们也能够在输出模块中用export default指定默认输出:
export default function(){}; --好比一个匿名函数或对象
而后本身在加载的时候给接收的函数/对象命名:
import customName from strUrl;
*import后不用加{}。由于export default在模块中只能使用一次,只输出一个变量/方法/class。
*不管export default输出的是否是匿名,都视为匿名。
*除了默认输出外还想加载其余变量:
import customName,{value_x,method_x} from strUrl;
*export * from strOtherMod 命令,先加载strOtherMod 再将其输出,*会忽略strOtherMod 的默认输出。
-------------------------------------------------------------分割线----------------------------------------------------------------
在实际生产中经常使用到webpack。webpack有code-spliting功能,容许咱们分割代码,实现模块静态/动态加载。
webpack有三种代码分离方法:
1.打包时在entry部署要打包几个chunk。
2.使用CommonsChunkPlugin插件去重和分离chunk。
3.Dynamic Imports:经过模块的内联函数动态导入代码(重点)。
import:
webpack使用import语法来实现模块的动态导入,这里import会生成一个promise对象:import('path/to/module') -> Promise,如下是官方例子:
if ( module.hot ) {
import('lodash').then(_ => {
// Do something with lodash (a.k.a '_')...
})
} --记住,then()中return的变量会做为后续then(param)的参数prama
在这里,import()会被webpack看成一个代码分割点(split point),所要import的文件会被另外打包成一个chunk,等须要时再加载。
使用时报错:
Module build failed: SyntaxError: D:/te/src/js/third.js: 'import' and 'export' may only appear at the top level (251:1)
根据webpack官网案例,案例中能成功,这里的报错有说是webpack并无按正确的语法来对待import,有网友说须要插件如:syntax-dynamic-import,
也有说babel的presets要加latest和es2015,个人babel配置和presets是没问题的,估计是插件,这里留下这个问题。
lazy-loading(须要时加载):
button.onclick = e => import(/* webpackChunkName: "print" */ './print')
.then(module => {
var print = module.default;
print();
});
官网例子很浅显,触发某个事件的时候再import模块,就像图片廊等用户滚动的时候再加载更多图片一个道理。
CommonJS:
webpack也支持commonjs,commonjs模块主要分为三块:模块引用require、模块定义exports、模块标志module(即模块自己)。
在服务器端,require(strUrl)是同步的,因为服务器在本地硬盘读取文件,速度很快,故而没问题,但浏览器端必须使用异步方法,于是有了AMD/CMD。
webpack实现的commonjs有:
1.require(strUrl); --同步
2.require.resolve(strUrl) --检索(或者说返回)strUrl模块的id。
3.require.cache(module.id)
--模块被require后只执行一次,也只返回一个exports对象。官网表示,在某些极端状况会须要屡次require同一个模块,也即重复执行某个require(获取module并执行回调);
于是能够执行那面的代码:
delete require.cache[require.resolve("dependency")];
大意是删除本来加载完的模块的id,让js能够再次加载模块并执行回调。
4.require.ensure([dependencies],callback(require),chunkName_str);
--这是webpack的require api里惟一一个能够实现异步加载的函数。
第一个参数是模块依赖的名称数组(这些依赖是执行callback须要的);
第二个是回调,qi,其形参require容许咱们执行进一步的require.ensure;
第三个是chunk名称,require.ensure的代码会被打包到另外一个chunk乘机加载,该参数就是这个chunk的名称。同名的chunk会被打包在一块儿。
//------------------------------------------------------------------------分割线---------------------------------------------------------------------------------------------------------------
使用vue的异步组件:
vue定义全局组件的方式是:
Vue.component('name',optionObj);
文档说,“Vue.js 容许将组件定义为一个工厂函数,动态地解析组件的定义”:
--------------------------------------引用-------------------------------------------
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// Pass the component definition to the resolve callback
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})
工厂函数接收一个 resolve 回调,在收到从服务器下载的组件定义时调用。也能够调用 reject(reason) 指示加载失败。
这里 setTimeout 只是为了演示。怎么获取组件彻底由你决定。
---------------------------------------------------------------------------------------------
因此肯定第一点:vue中异步组件的实现,是把 Vue.component('name',optionObj)中optionObj替换为一个函数,
这个函数执行异步任务,获取组件的定义并执行回调。
第二点是:当须要用到异步组件的时候,每每是模块已经足够大,这时候每每是使用.vue单文件组件,自包含template、css和其余options。
我我的对文档中的方法不太能理解:
后来有人解释说;这总方式是能够的,但省略了一些生产上的具体代码,实际上应该这样写:
<script>
import Vue from 'vue'
const name_ = Vue.component('name', function (resolve) {
require(['./service-search.vue'], resolve)
})
export default{
data(){
return {}
},
methods: {},
components: {
name: name_ //也能够更简便地将function (resolve){}替换这里的name_
}
}
</script>
vue路由:
另外,我也在学习vue路由时使用异步组件,用的是github上同行的写法:
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
import Vuex from 'vuex'
const setting = resolve => require.ensure([], () => resolve(require('./components/setting.vue')), 'setting');
Vue.use(VueRouter);
Vue.use(VueResource);
Vue.use(Vuex);
const routes=[
{path:'/setting',component:setting},
];
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes
})
new Vue({
router,
store,
el: '#app',
render: h => h(App)
});
实测可行。今天先到这里。