UNPKG

4.12 kBJavaScriptView Raw
1var _ = require('lodash');
2var async = require('async');
3var fs = require('graceful-fs');
4var glob = require('glob');
5var iconv = require('iconv-lite');
6var mkdirp = require('mkdirp');
7var mutil = require('miaow-util');
8var path = require('path');
9var Tapable = require('tapable');
10
11var TaskContext = require('./TaskContext');
12
13function Compilation() {
14 Tapable.call(this);
15 _.bindAll(this);
16
17 this.modules = {};
18
19 // 创建的模块
20 this.emitModules = {};
21}
22
23Compilation.prototype = Object.create(Tapable.prototype);
24Compilation.prototype.constructor = Compilation;
25
26Compilation.prototype.getFiles = function(callback) {
27 glob('**/*', {
28 cwd: this.context,
29 ignore: this.exclude.concat(['**/miaow.config.js']),
30 nodir: true
31 }, function(err, files) {
32 callback(err, (files || []).map(function(file) {
33 return mutil.relative('', file);
34 }));
35 });
36};
37
38// 创建模块
39Compilation.prototype.createModules = function(files, callback) {
40 async.map(files, this.createModule, callback);
41};
42
43Compilation.prototype.createModule = function(file, contents, callback) {
44 if (_.isFunction(contents)) {
45 callback = contents;
46 contents = null;
47 }
48
49 this.factory.create(file, contents, function(err, module) {
50 if (!err) {
51 this.modules[module.src] = module;
52 }
53
54 callback(err, module);
55 }.bind(this));
56};
57
58Compilation.prototype.buildModules = function(modules, callback) {
59 this.applyPluginsAsyncSeries('build-modules', this.modules, function(err) {
60 if (err) {
61 return callback(err);
62 }
63
64 async.eachSeries(
65 this.modules,
66 this.buildModule,
67 callback);
68 }.bind(this));
69};
70
71Compilation.prototype.buildModule = function(module, callback) {
72 var taskContext = new TaskContext(this, module);
73
74 this.applyPluginsAsyncSeries('build-module', module, taskContext, function(err) {
75 if (err) {
76 return callback(err);
77 }
78
79 module.doBuild(taskContext).then(function() {
80 callback(null, module);
81 }, callback);
82 });
83};
84
85Compilation.prototype.resolveFile = function(context, request, options, callback) {
86 if (_.isFunction(options)) {
87 callback = options;
88 options = {};
89 }
90
91 this.resolver.resolve(context, request, options, callback);
92};
93
94Compilation.prototype.resolveModule = function(context, request, options, callback) {
95 if (_.isFunction(options)) {
96 callback = options;
97 options = {};
98 }
99
100 // module://src 格式的路径解析
101 var moduleSchemaRegexp = /^module:\/\//;
102 if (moduleSchemaRegexp.test(request)) {
103 var module = this.modules[request.replace(moduleSchemaRegexp, '')];
104 return callback(module ? null : new Error(request + '未被查找到!'), module);
105 }
106
107 this.resolver.resolve(context, request, options, function(err, file) {
108 if (err) {
109 return callback(err);
110 }
111
112 var src = mutil.relative(this.context, file);
113
114 var module = this.modules[src];
115
116 if (module) {
117 this.buildModule(module, callback);
118 } else {
119 async.waterfall([
120 this.createModule.bind(this, src),
121 this.buildModule
122 ], callback);
123 }
124 }.bind(this));
125};
126
127Compilation.prototype.emitFile = function(dest, contents, charset, callback) {
128 if (!/utf[\-]?8/i.test(charset)) {
129 contents = iconv.encode(contents.toString(), charset);
130 }
131
132 var abspath = path.resolve(this.output, dest);
133
134 async.series([
135 _.partial(mkdirp, path.dirname(abspath)),
136 fs.writeFile.bind(fs, abspath, contents)
137 ], callback);
138};
139
140Compilation.prototype.emitModule = function(src, contents, callback) {
141 src = mutil.relative('', src);
142
143 var module = this.modules[src];
144
145 if (module) {
146 this.buildModule(module, callback);
147 } else {
148 async.waterfall([
149 this.createModule.bind(this, src, contents),
150 function(module, callback) {
151 this.emitModules[src] = module;
152 callback(null, module);
153 }.bind(this),
154 this.buildModule
155 ], callback);
156 }
157};
158
159// 编译
160Compilation.prototype.seal = function(callback) {
161 async.waterfall([
162 this.getFiles,
163 this.createModules,
164 this.buildModules
165 ], callback);
166};
167
168module.exports = Compilation;