前端模块管理!
从2014年yahoo宣布停止开发YUI,曾经想一套框架可以包含各种各样的开发需求,而其实,大型框架无法应对我们日益增长的开发需求。
去年很流行用grunt来管理各个模块,但是,逐渐发现grunt的缺点,一是配置任务的方式,grunt是一种通过配置文件来执行任务,不够灵活。二是运行任务的方式,grunt多是一种顺序执行的概念。
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build: {
src: 'src/<%= pkg.name %>.js',
dest: 'build/<%= pkg.name %>.min.js'
}
}
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task(s).
grunt.registerTask('default', ['uglify']);
};
有些人开始转向gulp来管理,因为gulp是基于数据流的形式来运行以及并发的运行模式, 具体参考:gulp vs grunt。
var gulp = require('gulp');
gulp.task('default', function() {
// place code for your default task here
});
而随着项目发展,我们发现,由于配置文件的形式与网站页面数量的增多导致维护越来越困难。
我们希望通过一个打包来完成加载模块、合并文件、预处理文件等操作。
欢迎新人webpack登场
webpack是一个模块打包器,一个根据依赖加载模块并打包生成静态文件。
在认识新人之前,我们先充电一下:
- CommonJS
- AMD
CommonJS让每个模块在自己的命名空间内运行来解决了js的作用域问题, 通过两个工具(require和module)完成以上功能 require: 加载一个模块到现在的作用域内。 module: 提供模块暴露出来的接口功能。
// moduleA.js
module.exports = function( value ){
return value*2;
}
// moduleB.js
var multiplyBy2 = require('moduleA');
var result = multiplyBy2(4);
// 8
AMD(Asynchronous Module Definition)异步模块定义, 对于同步加载的缺陷,我们用COMMONJS来加载异步模块, 而AMD就是一种异步模块定义的方式。
模块用一个define函数来定义:
define(id?: String, dependencies?: String[], factory: Function|Object);
// id: 定义模块名字, 可选
// dependencies: 定义模块依赖,数组类型
// factory: 最后一个是定义该模块的人,可以是函数也可以是对象
// Example:
define('myModule', ['jquery'], function($) {
// $ is the export of the jquery module.
$('body').text('hello world');
});
// and use it
define(['myModule'], function(myModule) {});
Anoymous module匿名模块
define(['jquery'], function($) {
$('body').text('hello world');
});
Multiple dependencies 多个模块
define(['jquery', './math.js'], function($, math) {
// $ and math are the exports of the jquery module.
$('body').text('hello world');
});
Export value, 那如果运用模块呢, 让模块暴露一些春光给我们呢:
define(['jquery'], function($) {
var HelloWorldize = function(selector){
$(selector).text('hello world');
};
return HelloWorldize;
});
说了这么多,那跟webpack有什么关系呢?webpack是模块打包器,支持多种模块定义方式:
- <script-tag> style
- CommonJs
- AMD and some dialects of is
- ES6 modules
- and more…
我们根据文档,来看怎么使用:
创建一个entry.js
// entry.js
document.write('It works.');
创建一个index.html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript" src="bundle.js" charset="utf-8"></script>
</body>
</html>
接下来运行下面命令:
$ webpack ./entry.js bundle.js
这个步骤将编译文件并创建一个捆绑的文件, 打开Index.html:
It works.
我觉得文档例子更全,所以我们分享一点使用心得:
工具这么多,最主要是几点: 内容嵌入、定位资源、声明依赖。在一开始选择的时候,最好分析这些工具的目录架构与开发模式,我们需要做到迁移方便。 什么是迁移方便呢?也就是说,我们不喜欢因为工具的bug而导致项目出问题,我们也不喜欢项目一旦用了某个工具就摆脱不了。
感觉定了个大主题,说的东西太大范围,并不能每样详细说明,请见谅。