OLD | NEW |
---|---|
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:io'; | 6 import 'dart:io'; |
7 import 'dart:convert' show JsonEncoder; | |
7 | 8 |
8 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
9 import 'package:barback/barback.dart'; | 10 import 'package:barback/barback.dart'; |
10 import 'package:bazel_worker/bazel_worker.dart'; | 11 import 'package:bazel_worker/bazel_worker.dart'; |
11 import 'package:cli_util/cli_util.dart' as cli_util; | 12 import 'package:cli_util/cli_util.dart' as cli_util; |
12 import 'package:path/path.dart' as p; | 13 import 'package:path/path.dart' as p; |
13 | 14 |
14 import '../dart.dart'; | 15 import '../dart.dart'; |
15 import '../io.dart'; | 16 import '../io.dart'; |
17 import 'module.dart'; | |
16 import 'module_reader.dart'; | 18 import 'module_reader.dart'; |
17 import 'scratch_space.dart'; | 19 import 'scratch_space.dart'; |
18 import 'summaries.dart'; | 20 import 'summaries.dart'; |
19 import 'workers.dart'; | 21 import 'workers.dart'; |
20 | 22 |
23 // JavaScript snippet to determine the directory a script was run from. | |
24 final _currentDirectoryScript = r''' | |
25 var _currentDirectory = (function () { | |
26 var _url; | |
27 var lines = new Error().stack.split('\n'); | |
28 function lookupUrl() { | |
29 if (lines.length > 2) { | |
30 var match = lines[1].match(/^\s+at (.+):\d+:\d+$/); | |
31 // Chrome. | |
32 if (match) return match[1]; | |
33 // Chrome nested eval case. | |
34 match = lines[1].match(/^\s+at eval [(](.+):\d+:\d+[)]$/); | |
35 if (match) return match[1]; | |
36 // Edge. | |
37 match = lines[1].match(/^\s+at.+\((.+):\d+:\d+\)$/); | |
38 if (match) return match[1]; | |
39 // Firefox. | |
40 return lines[0].match(/[<][@](.+):\d+:\d+$/)[1]; | |
41 } | |
42 // Safari. | |
43 return lines[0].match(/(.+):\d+:\d+$/)[1]; | |
44 } | |
45 _url = lookupUrl(); | |
46 var lastSlash = _url.lastIndexOf('/'); | |
47 if (lastSlash == -1) return _url; | |
48 var currentDirectory = _url.substring(0, lastSlash + 1); | |
49 return currentDirectory; | |
50 })(); | |
51 '''; | |
52 | |
21 /// Returns whether or not [dartId] is an app entrypoint (basically, whether or | 53 /// Returns whether or not [dartId] is an app entrypoint (basically, whether or |
22 /// not it has a `main` function). | 54 /// not it has a `main` function). |
23 Future<bool> isAppEntryPoint( | 55 Future<bool> isAppEntryPoint( |
24 AssetId dartId, Future<Asset> getAsset(AssetId id)) async { | 56 AssetId dartId, Future<Asset> getAsset(AssetId id)) async { |
25 assert(dartId.extension == '.dart'); | 57 assert(dartId.extension == '.dart'); |
26 var dartAsset = await getAsset(dartId); | 58 var dartAsset = await getAsset(dartId); |
27 // Skip reporting errors here, dartdevc will report them later with nicer | 59 // Skip reporting errors here, dartdevc will report them later with nicer |
28 // formatting. | 60 // formatting. |
29 var parsed = parseCompilationUnit(await dartAsset.readAsString(), | 61 var parsed = parseCompilationUnit(await dartAsset.readAsString(), |
30 suppressErrors: true); | 62 suppressErrors: true); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 // | 115 // |
84 // See https://github.com/dart-lang/sdk/issues/27262 for the root issue | 116 // See https://github.com/dart-lang/sdk/issues/27262 for the root issue |
85 // which will allow us to not rely on the naming schemes that dartdevc uses | 117 // which will allow us to not rely on the naming schemes that dartdevc uses |
86 // internally, but instead specify our own. | 118 // internally, but instead specify our own. |
87 var appModuleScope = p.url | 119 var appModuleScope = p.url |
88 .split(p.url.withoutExtension( | 120 .split(p.url.withoutExtension( |
89 p.url.relative(dartEntrypointId.path, from: moduleDir))) | 121 p.url.relative(dartEntrypointId.path, from: moduleDir))) |
90 .join("__") | 122 .join("__") |
91 .replaceAll('.', '\$46'); | 123 .replaceAll('.', '\$46'); |
92 | 124 |
93 // Modules not under a `packages` directory need custom module paths. | 125 // Map from module name to module path. |
94 var customModulePaths = <String>[]; | 126 // Modules outside of the `packages` directory have different module path |
127 // and module names. | |
128 var modulePaths = new Map<String, String>(); | |
129 modulePaths[appModulePath] = appModulePath; | |
130 modulePaths['dart_sdk'] = 'dart_sdk'; | |
131 | |
95 var transitiveDeps = await moduleReader.readTransitiveDeps(module); | 132 var transitiveDeps = await moduleReader.readTransitiveDeps(module); |
96 for (var dep in transitiveDeps) { | 133 for (var dep in transitiveDeps) { |
97 if (dep.dir != 'lib') { | 134 if (dep.dir != 'lib') { |
98 var relativePath = p.url.relative(p.url.join(moduleDir, dep.name), | 135 var relativePath = p.url.relative(p.url.join(moduleDir, dep.name), |
99 from: p.url.dirname(bootstrapId.path)); | 136 from: p.url.dirname(bootstrapId.path)); |
100 customModulePaths.add('"${dep.dir}/${dep.name}": "$relativePath"'); | 137 var jsModuleName = '${dep.dir}/${dep.name}'; |
138 | |
139 modulePaths[jsModuleName] = relativePath; | |
101 } else { | 140 } else { |
102 var jsModuleName = 'packages/${dep.package}/${dep.name}'; | 141 var jsModuleName = 'packages/${dep.package}/${dep.name}'; |
103 var actualModulePath = p.url.relative( | 142 var actualModulePath = p.url.relative( |
104 p.url.join(moduleDir, jsModuleName), | 143 p.url.join(moduleDir, jsModuleName), |
105 from: p.url.dirname(bootstrapId.path)); | 144 from: p.url.dirname(bootstrapId.path)); |
106 if (jsModuleName != actualModulePath) { | 145 modulePaths[jsModuleName] = actualModulePath; |
107 customModulePaths.add('"$jsModuleName": "$actualModulePath"'); | |
108 } | |
109 } | 146 } |
110 } | 147 } |
111 | 148 |
112 var bootstrapContent = ''' | 149 var bootstrapContent = ''' |
150 (function() { | |
151 $_currentDirectoryScript | |
152 | |
153 let modulePaths = ${const JsonEncoder.withIndent(' ').convert(modulePaths)}; | |
154 | |
155 if(!window.\$dartLoader) { | |
156 window.\$dartLoader = { | |
157 moduleIdToUrl: new Map(), | |
158 urlToModuleId: new Map(), | |
159 rootDirectories: new Set(), | |
160 }; | |
161 } | |
162 | |
163 let customModulePaths = {}; | |
164 window.\$dartLoader.rootDirectories.add(_currentDirectory); | |
165 for (let moduleName of Object.getOwnPropertyNames(modulePaths)) { | |
166 let modulePath = modulePaths[moduleName]; | |
167 if (modulePath != moduleName) { | |
168 customModulePaths[moduleName] = modulePath; | |
169 } | |
170 var src = _currentDirectory + modulePath + '.js'; | |
171 if (window.\$dartLoader.moduleIdToUrl.has(moduleName)) { | |
172 continue; | |
173 } | |
174 \$dartLoader.moduleIdToUrl.set(moduleName, src); | |
175 \$dartLoader.urlToModuleId.set(src, moduleName); | |
176 } | |
177 | |
113 require.config({ | 178 require.config({ |
114 waitSeconds: 30, | 179 waitSeconds: 30, |
115 paths: { | 180 paths: customModulePaths |
116 ${customModulePaths.join(',\n ')} | |
117 } | |
118 }); | 181 }); |
119 | 182 |
120 require(["$appModulePath", "dart_sdk"], function(app, dart_sdk) { | 183 require(["$appModulePath", "dart_sdk"], function(app, dart_sdk) { |
184 // This import is only needed for chrome debugging. We should provide an | |
185 // option to compile without it. | |
186 dart_sdk._debugger.registerDevtoolsFormatter(); | |
187 | |
121 dart_sdk._isolate_helper.startRootIsolate(() => {}, []); | 188 dart_sdk._isolate_helper.startRootIsolate(() => {}, []); |
189 if (window.\$dartStackTraceUtility && !window.\$dartStackTraceUtility.ready) { | |
190 window.\$dartStackTraceUtility.ready = true; | |
191 let dart = dart_sdk.dart; | |
192 window.\$dartStackTraceUtility.setSourceMapProvider( | |
193 function(url) { | |
194 var module = window.\$dartLoader.urlToModuleId.get(url); | |
195 if (!module) return null; | |
196 return dart.getSourceMap(module); | |
197 }); | |
198 } | |
199 window.postMessage({ type: "DDC_STATE_CHANGE", state: "start" }, "*"); | |
200 | |
122 app.$appModuleScope.main(); | 201 app.$appModuleScope.main(); |
123 }); | 202 }); |
203 })(); | |
124 '''; | 204 '''; |
125 outputCompleters[bootstrapId] | 205 outputCompleters[bootstrapId] |
126 .complete(new Asset.fromString(bootstrapId, bootstrapContent)); | 206 .complete(new Asset.fromString(bootstrapId, bootstrapContent)); |
127 | 207 |
128 var bootstrapModuleName = p.withoutExtension( | 208 var bootstrapModuleName = p.withoutExtension( |
129 p.relative(bootstrapId.path, from: p.dirname(dartEntrypointId.path))); | 209 p.relative(bootstrapId.path, from: p.dirname(dartEntrypointId.path))); |
130 var entrypointJsContent = ''' | 210 var entrypointJsContent = ''' |
131 var el = document.createElement("script"); | 211 var el = document.createElement("script"); |
212 el = document.createElement("script"); | |
jakemac
2017/05/19 14:38:06
duplicate code with the line right above :)
Jacob
2017/05/19 16:24:02
Done.
| |
213 el.defer = true; | |
214 el.async = false; | |
215 el.src = "dart_stack_trace_mapper.js"; | |
216 document.head.appendChild(el); | |
217 | |
218 el = document.createElement("script"); | |
132 el.defer = true; | 219 el.defer = true; |
133 el.async = false; | 220 el.async = false; |
134 el.src = "require.js"; | 221 el.src = "require.js"; |
135 el.setAttribute("data-main", "$bootstrapModuleName"); | 222 el.setAttribute("data-main", "$bootstrapModuleName"); |
136 document.head.appendChild(el); | 223 document.head.appendChild(el); |
137 '''; | 224 '''; |
138 outputCompleters[jsEntrypointId] | 225 outputCompleters[jsEntrypointId] |
139 .complete(new Asset.fromString(jsEntrypointId, entrypointJsContent)); | 226 .complete(new Asset.fromString(jsEntrypointId, entrypointJsContent)); |
140 | 227 |
141 if (mode == BarbackMode.DEBUG) { | 228 if (mode == BarbackMode.DEBUG) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 '--dart-sdk-summary=$sdk_summary', | 271 '--dart-sdk-summary=$sdk_summary', |
185 // TODO(jakemac53): Remove when no longer needed, | 272 // TODO(jakemac53): Remove when no longer needed, |
186 // https://github.com/dart-lang/pub/issues/1583. | 273 // https://github.com/dart-lang/pub/issues/1583. |
187 '--unsafe-angular2-whitelist', | 274 '--unsafe-angular2-whitelist', |
188 '--modules=amd', | 275 '--modules=amd', |
189 '--dart-sdk=${sdkDir.path}', | 276 '--dart-sdk=${sdkDir.path}', |
190 '--module-root=${scratchSpace.tempDir.path}', | 277 '--module-root=${scratchSpace.tempDir.path}', |
191 '--library-root=${p.dirname(jsOutputFile.path)}', | 278 '--library-root=${p.dirname(jsOutputFile.path)}', |
192 '--summary-extension=${linkedSummaryExtension.substring(1)}', | 279 '--summary-extension=${linkedSummaryExtension.substring(1)}', |
193 '--no-summarize', | 280 '--no-summarize', |
281 '--source-map', | |
jakemac
2017/05/19 14:38:06
We should only include these in DEBUG mode, a few
Jacob
2017/05/19 16:24:02
Done.
| |
282 '--source-map-comment', | |
283 '--inline-source-map', | |
194 '-o', | 284 '-o', |
195 jsOutputFile.path, | 285 jsOutputFile.path, |
196 ]); | 286 ]); |
197 | 287 |
198 if (mode == BarbackMode.RELEASE) { | 288 if (mode == BarbackMode.RELEASE) { |
199 request.arguments.add('--no-source-map'); | 289 request.arguments.add('--no-source-map'); |
200 } | 290 } |
201 | 291 |
202 // Add environment constants. | 292 // Add environment constants. |
203 environmentConstants.forEach((key, value) { | 293 environmentConstants.forEach((key, value) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 } finally { | 387 } finally { |
298 for (var id in completers.keys) { | 388 for (var id in completers.keys) { |
299 if (!completers[id].isCompleted) { | 389 if (!completers[id].isCompleted) { |
300 completers[id].completeError(new AssetNotFoundException(id)); | 390 completers[id].completeError(new AssetNotFoundException(id)); |
301 } | 391 } |
302 } | 392 } |
303 } | 393 } |
304 }(); | 394 }(); |
305 return futures; | 395 return futures; |
306 } | 396 } |
OLD | NEW |