UNPKG

5.59 kBJavaScriptView Raw
1var fs = require('fs');
2var path = require('path');
3var assign = require('object-assign');
4var relative = require('require-relative');
5
6var ROOT = null,
7 packages = {
8 process: '*',
9 buffer: '*'
10 },
11 options = null;
12
13var cachePkgs = {},
14 cacheFiles = {},
15 cacheBrowser = {};
16
17function resolveNodeRequire(id, refDir) {
18 var sysPath = null;
19 try {
20 sysPath = relative.resolve(id, refDir);
21 } catch (ex) {
22 }
23 // node内置模块
24 if (sysPath && sysPath.match(/^[\w\-]+$/)) {
25 sysPath = null;
26 }
27 if (sysPath && sysPath.match(/^(.*[\\\/]node_modules[\\\/][^\/\\]+)[\\\/](.+?)$/)) {
28 // 处理package.json browser
29 var root = RegExp.$1,
30 path = './' + RegExp.$2.replace(/\\/g, '\/'),
31 pkg = fis.util(root, 'package.json');
32 if (!cacheBrowser[sysPath]) {
33 var json = null,
34 browser = null;
35 try {
36 json = fs.existsSync(pkg) && JSON.parse(fs.readFileSync(pkg).toString());
37 } catch (ex) {
38 }
39 if (json && json.browser) {
40 if (typeof json.browser === 'string' && id.match(/^[\w-]+$/)) {
41 browser = json.browser;
42 } else if (typeof json.browser === 'object') {
43 if (json.browser[path]) {
44 browser = json.browser[path];
45 }
46 }
47 }
48 [
49 options.browser[id] || null,
50 options.tryMin && 'dist/' + id + '.min.js',
51 browser
52 ].every(function(sub) {
53 if (sub) {
54 var fullpath = fis.util(root, sub);
55 if (fs.existsSync(fullpath)) {
56 sysPath = fullpath;
57 return false;
58 }
59 }
60 return true;
61 });
62
63 cacheBrowser[sysPath] = sysPath;
64 } else {
65 sysPath = cacheBrowser[sysPath] || sysPath;
66 }
67 }
68 return sysPath;
69}
70
71function resolvePkg(id, refFile) {
72 var sysPath = null,
73 pkgName = id.match(/^([\w\-]+)/) && RegExp.$1 || null,
74 isAbsolute = !!pkgName,
75 refModules = resolveSelf(refFile);
76 // 必须在packages.json里声明
77 if (isAbsolute && !refModules && !packages[pkgName]) {
78 return;
79 }
80 // 非相对路径的可以使用缓存
81 if (isAbsolute && !refModules && cachePkgs[id]) {
82 return cachePkgs[id];
83 }
84 sysPath = resolveNodeRequire(id, refModules && refModules.dir || refFile.fullname);
85 if (sysPath && sysPath.match(/([\\\/]node_modules\b.*)$/)) {
86 // 创建node_modules文件
87 var subpath = RegExp.$1,
88 inProject = sysPath.indexOf(ROOT) === 0,
89 file = null;
90
91 if (!cacheFiles[subpath]) {
92 if (inProject) {
93 // 文件在项目下
94 file = fis.uri(path.basename(sysPath), path.dirname(sysPath)).file;
95 } else {
96 // 不在项目下
97 file = fis.file(
98 fis.project.getProjectPath(),
99 subpath
100 );
101 file.setContent(fs.readFileSync(sysPath).toString());
102 }
103 // node_modules标志
104 file._node_modules = {
105 fullpath: sysPath,
106 dir: path.dirname(sysPath)
107 };
108 if (!inProject) {
109 // 必须先设置_node_modules
110 fis.compile(file);
111 }
112 cacheFiles[subpath] = file;
113 } else {
114 file = cacheFiles[subpath];
115 }
116 var ret = {
117 id: subpath,
118 file: file
119 };
120 if (isAbsolute) {
121 cachePkgs[id] = ret;
122 }
123 return ret;
124 }
125 return null;
126}
127
128function resolveSelf(file) {
129 return file._node_modules || null;
130}
131
132/**
133 * watch时补充文件
134 */
135function pushFiles(ret) {
136 Object.keys(cacheFiles).forEach(function(key) {
137 var file = cacheFiles[key],
138 id = file.getId();
139 if (!ret.src[file.subpath]) {
140 ret.src[file.subpath] = file;
141 _collect(ret, file);
142 }
143 });
144}
145
146function _collect(ret, file) {
147 if (file.release && file.useMap) {
148 //add resource map
149 var id = file.getId();
150 ret.ids[id] = file;
151 var res = file.map = ret.map.res[id] = {
152 uri: file.getUrl(),
153 type: file.rExt.replace(/^\./, '')
154 };
155 for (var key in file.extras) {
156 if (file.extras.hasOwnProperty(key)) {
157 res.extras = file.extras;
158 break;
159 }
160 }
161 if (file.requires && file.requires.length) {
162 res.deps = file.requires;
163 }
164 }
165 if (file._isResourceMap) {
166 console.warn('ignore _isResourceMap: ' + file.getId());
167 }
168}
169
170function init(_options) {
171 ROOT = fis.project.getProjectPath();
172 options = _options;
173
174 // 读取运行环境的packages.json
175 var pkgFile = fis.util(process.cwd(), 'package.json'),
176 pkgJson = null;
177 if (fs.existsSync(pkgFile)) {
178 try {
179 pkgJson = JSON.parse(fs.readFileSync(pkgFile).toString());
180 } catch (ex) {
181 }
182 pkgJson = pkgJson || {};
183 packages = assign(packages, pkgJson.peerDependencie || {}, pkgJson.dependencies || {});
184 }
185}
186
187exports.resolvePkg = resolvePkg;
188exports.resolveSelf = resolveSelf;
189exports.pushFiles = pushFiles;
190exports.init = init;
191