-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
197 lines (169 loc) · 5.74 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
'use strict'
var depsParser = require('./dependencyParser')
var gutil = require('gulp-util')
var PLUGIN_NAME = 'gulp-dep-pack'
var minimatch = require('minimatch')
var path = require('path')
var fs = require('fs')
var os = require('os')
var _ = require('underscore')
var through = require('through2')
var vinylFiles
var resourceMap
var config = {}
var MODULAR_FILE = path.join(__dirname, 'modular/modular.js')
var MODULAR_ASYNC_FILE = path.join(__dirname, '/modular/modular_async.js')
var modularjs = fs.readFileSync(MODULAR_FILE, {encoding: 'utf-8'})
var modularjs_async = fs.readFileSync(MODULAR_ASYNC_FILE, {encoding: 'utf-8'})
var defaultCfg = {
baseUrl: '/',
shim: {},
genResDeps: false,
silent: false,
entries: '**/index.js'
}
function processConf (conf) {
var baseUrl = conf.baseUrl
if (baseUrl && baseUrl.charAt(baseUrl.length - 1) !== '/') {
conf.baseUrl = baseUrl + '/'
}
config = _.defaults(conf, defaultCfg)
}
function writeBundle (moduleId) {
var vinylFile = vinylFiles[moduleId]
vinylFile.contents = new Buffer(writeDeps(moduleId))
}
function writeDeps (moduleId) {
var module = resourceMap[moduleId]
var vinylFile = vinylFiles[moduleId]
var contents = ''
// use avaiable transformed contents first
if (module.isTransformed) {
return vinylFile.contents.toString()
}
module.deps.forEach(function (moduleId) {
contents += writeDeps(moduleId)
})
contents += wrapModuleDef(moduleId)
// if main entrypoint, add module manage snippet in front of it.
if (module.isEntry && module.parentModuleId === null) {
contents = (module.asyncDeps.length ? modularjs_async : modularjs) +
os.EOL + writeJsConfig() + contents
// insert require.
contents += os.EOL + 'require(\'' + moduleId + '\')' + os.EOL
}
// save transformed contents for subsequent possible uses
module.isTransformed = true
vinylFile.contents = new Buffer(contents)
// write asynchronized entry.
module.asyncDeps.forEach(function (moduleId) {
writeBundle(moduleId)
})
return contents
}
function writeJsConfig () {
return 'require.config(' +
JSON.stringify({
baseUrl: config.baseUrl
}, null, 2) +
')'
}
function wrapModuleDef (moduleId) {
var vinylFile = vinylFiles[moduleId]
var module = resourceMap[moduleId]
var extname = path.extname(moduleId)
var fileContents = vinylFile.contents.toString()
var contents = ''
var EOL = os.EOL
contents += EOL +
'define(\'' + moduleId + '\', function (require, exports, module){'
if (extname === '.js') {
contents += EOL + fileContents
} else if (extname === '.css') {
fileContents = fileContents.replace(/\\/g, '\\\\').replace(/'/g, '\\\'')
contents += EOL + ' var style = document.createElement("style")' +
EOL + ' var contents = \'' + fileContents + '\'' +
EOL + ' style.type = "text/css"' +
EOL + ' if (style.styleSheet) {' +
EOL + ' style.styleSheet.cssText = contents' +
EOL + ' } else {' +
EOL + ' style.innerHTML = contents' +
EOL + ' }' +
EOL + ' document.getElementsByTagName("head")[0].appendChild(style)'
} else if (extname === '.json') {
contents += EOL + ' return ' + fileContents + ''
} else if (extname === '.tpl' || extname === '.tmpl') {
contents += EOL + 'return ' + _.template(fileContents, {'variable': 'data'}).source
} else {
throw new gutil.PluginError(PLUGIN_NAME, 'Unknow file type: ' + vinylFiles.path)
}
if (module.shim && module.exports) {
contents += EOL + ' module.exports = ' + module.exports + ''
}
contents += EOL + '})' + EOL
return contents
}
module.exports = function pack (conf) {
resourceMap = {}
vinylFiles = {}
processConf(conf)
depsParser.setVinylFiles(vinylFiles)
depsParser.setConfig(config)
depsParser.setResourceMap(resourceMap)
var stream = through.obj(function (file, encoding, cb) {
var moduleId = file.relative
if (file.isStream()) {
return cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'))
}
if (file.isBuffer()) {
if (process.platform === 'win32') {
moduleId = moduleId.replace(/\\+/g, '/')
}
// collect files for the following process
vinylFiles[moduleId] = file
cb()
}
}, function (cb) {
var isErrorExist = false
// parse each entry file. combine it and its deps into a single file.
Object.keys(vinylFiles).every(function (moduleId) {
if (minimatch(moduleId, config.entries)) {
try {
// parse deps
depsParser.parse(moduleId)
// write as a bundle
writeBundle(moduleId)
return true
} catch (ex) {
isErrorExist = true
cb(ex)
return false
}
} else {
return true
}
})
if (!isErrorExist) {
Object.keys(vinylFiles).forEach(function (moduleId) {
var module = resourceMap[moduleId]
if (!module) {
stream.push(vinylFiles[moduleId])
// ignore those not-entry and combined files
} else if (module.isEntry || !module.combined) {
stream.push(vinylFiles[moduleId])
}
})
// generate dependent relations json file.
if (config.genResDeps) {
var resourcesJson = new gutil.File({
path: 'resource_deps.json'
})
// gutil.log(JSON.stringify(resourceMap, null, 2))
resourcesJson.contents = new Buffer(JSON.stringify(resourceMap, null, 2))
stream.push(resourcesJson)
}
cb()
}
})
return stream
}