Sourcemaps support for RAM
Summary:This rev adds support for production sourcemaps on RAM. When we inject a module into JSC we use the original `sourceURL` and specify the `startingLineNumber` of the module relative to a "regular" bundle. By doing so, when an error is thrown, JSC will include the provided `sourceURL` as the filename and will use the indicated `startingLineNumber` to figure out on which line the error actually occurred. To make things a bit simpler and avoid having to deal with columns, we tweak the generated bundle so that each module starts on a new line. Since we cannot assure that each module's code will be on a single line as the minifier might break it on multiple (UglifyJS does so due to a bug on old versions of Chrome), we include on the index the line number that should be used when invoking `JSEvaluateScript`. Since the module length was not being used we replaced the placeholder we have there for the line number. Reviewed By: javache Differential Revision: D2997520 fb-gh-sync-id: 3243a489cbb5b48a963f4ccdd98ba63b30f53f3f shipit-source-id: 3243a489cbb5b48a963f4ccdd98ba63b30f53f3f
This commit is contained in:
parent
7338c5704e
commit
f99468de65
|
@ -32,10 +32,10 @@ NSString *const RCTJavaScriptContextCreatedNotification = @"RCTJavaScriptContext
|
||||||
|
|
||||||
static NSString *const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabled";
|
static NSString *const RCTJSCProfilerEnabledDefaultsKey = @"RCTJSCProfilerEnabled";
|
||||||
|
|
||||||
// TODO: add lineNo
|
|
||||||
typedef struct ModuleData
|
typedef struct ModuleData
|
||||||
{
|
{
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
|
uint32_t lineNo;
|
||||||
} ModuleData;
|
} ModuleData;
|
||||||
|
|
||||||
@interface RCTJavaScriptContext : NSObject <RCTInvalidating>
|
@interface RCTJavaScriptContext : NSObject <RCTInvalidating>
|
||||||
|
@ -668,6 +668,14 @@ static void freeModuleData(__unused CFAllocatorRef allocator, void *ptr)
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t readUint32(const void **ptr) {
|
||||||
|
uint32_t data;
|
||||||
|
memcpy(&data, *ptr, sizeof(uint32_t));
|
||||||
|
data = NSSwapLittleIntToHost(data);
|
||||||
|
*ptr += sizeof(uint32_t);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSData *)loadRAMBundle:(NSData *)script
|
- (NSData *)loadRAMBundle:(NSData *)script
|
||||||
{
|
{
|
||||||
__weak RCTJSCExecutor *weakSelf = self;
|
__weak RCTJSCExecutor *weakSelf = self;
|
||||||
|
@ -679,8 +687,9 @@ static void freeModuleData(__unused CFAllocatorRef allocator, void *ptr)
|
||||||
|
|
||||||
ModuleData *moduleData = (ModuleData *)CFDictionaryGetValue(strongSelf->_jsModules, moduleName.UTF8String);
|
ModuleData *moduleData = (ModuleData *)CFDictionaryGetValue(strongSelf->_jsModules, moduleName.UTF8String);
|
||||||
JSStringRef module = JSStringCreateWithUTF8CString((const char *)_bundle.bytes + moduleData->offset);
|
JSStringRef module = JSStringCreateWithUTF8CString((const char *)_bundle.bytes + moduleData->offset);
|
||||||
|
int lineNo = [moduleName isEqual:@""] ? 0 : moduleData->lineNo;
|
||||||
JSValueRef jsError = NULL;
|
JSValueRef jsError = NULL;
|
||||||
JSValueRef result = JSEvaluateScript(strongSelf->_context.ctx, module, NULL, strongSelf->_bundleURL, NULL, &jsError);
|
JSValueRef result = JSEvaluateScript(strongSelf->_context.ctx, module, NULL, strongSelf->_bundleURL, lineNo, NULL);
|
||||||
|
|
||||||
CFDictionaryRemoveValue(strongSelf->_jsModules, moduleName.UTF8String);
|
CFDictionaryRemoveValue(strongSelf->_jsModules, moduleName.UTF8String);
|
||||||
JSStringRelease(module);
|
JSStringRelease(module);
|
||||||
|
@ -706,26 +715,28 @@ static void freeModuleData(__unused CFAllocatorRef allocator, void *ptr)
|
||||||
memcpy(&tableLength, bytes + currentOffset, sizeof(tableLength));
|
memcpy(&tableLength, bytes + currentOffset, sizeof(tableLength));
|
||||||
tableLength = NSSwapLittleIntToHost(tableLength);
|
tableLength = NSSwapLittleIntToHost(tableLength);
|
||||||
|
|
||||||
uint32_t baseOffset = currentOffset + tableLength;
|
// offset where the code starts on the bundle
|
||||||
|
const uint32_t baseOffset = currentOffset + tableLength;
|
||||||
|
|
||||||
|
// skip table length
|
||||||
currentOffset += sizeof(baseOffset);
|
currentOffset += sizeof(baseOffset);
|
||||||
|
|
||||||
while (currentOffset < baseOffset) {
|
// pointer to first byte out of the index
|
||||||
const char *moduleName = (const char *)bytes + currentOffset;
|
const uint8_t *endOfTable = bytes + baseOffset;
|
||||||
uint32_t offset;
|
|
||||||
|
// pointer to current position on table
|
||||||
|
const uint8_t *tablePos = bytes + 2 * sizeof(uint32_t); // skip magic number and table length
|
||||||
|
|
||||||
|
while (tablePos < endOfTable) {
|
||||||
|
const char *moduleName = (const char *)tablePos;
|
||||||
|
|
||||||
// the space allocated for each module's metada gets freed when the module is injected into JSC on `nativeRequire`
|
// the space allocated for each module's metada gets freed when the module is injected into JSC on `nativeRequire`
|
||||||
ModuleData *moduleData = malloc(sizeof(moduleData));
|
ModuleData *moduleData = malloc(sizeof(ModuleData));
|
||||||
|
|
||||||
// skip module name and null byte terminator
|
tablePos += strlen(moduleName) + 1; // null byte terminator
|
||||||
currentOffset += strlen(moduleName) + 1;
|
|
||||||
|
|
||||||
// read and save offset
|
moduleData->offset = baseOffset + readUint32((const void **)&tablePos);
|
||||||
memcpy(&offset, bytes + currentOffset, sizeof(offset));
|
moduleData->lineNo = readUint32((const void **)&tablePos);
|
||||||
offset = NSSwapLittleIntToHost(offset);
|
|
||||||
moduleData->offset = baseOffset + offset;
|
|
||||||
|
|
||||||
// TODO: replace length with lineNo
|
|
||||||
currentOffset += sizeof(offset) * 2; // skip both offset and lenght
|
|
||||||
|
|
||||||
CFDictionarySetValue(_jsModules, moduleName, moduleData);
|
CFDictionarySetValue(_jsModules, moduleName, moduleData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const buildUnbundleSourcemap = require('./buildUnbundleSourcemap');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const Promise = require('promise');
|
const Promise = require('promise');
|
||||||
const writeSourceMap = require('./write-sourcemap');
|
const writeSourceMap = require('./write-sourcemap');
|
||||||
|
@ -26,23 +27,27 @@ function saveAsIndexedFile(bundle, options, log) {
|
||||||
const {
|
const {
|
||||||
'bundle-output': bundleOutput,
|
'bundle-output': bundleOutput,
|
||||||
'bundle-encoding': encoding,
|
'bundle-encoding': encoding,
|
||||||
dev,
|
|
||||||
'sourcemap-output': sourcemapOutput,
|
'sourcemap-output': sourcemapOutput,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
log('start');
|
log('start');
|
||||||
const {startupCode, modules} = bundle.getUnbundle({minify: !dev});
|
const {startupCode, modules} = bundle.getUnbundle();
|
||||||
log('finish');
|
log('finish');
|
||||||
|
|
||||||
log('Writing unbundle output to:', bundleOutput);
|
log('Writing unbundle output to:', bundleOutput);
|
||||||
const writeUnbundle = writeBuffers(
|
const writeUnbundle = writeBuffers(
|
||||||
fs.createWriteStream(bundleOutput),
|
fs.createWriteStream(bundleOutput),
|
||||||
buildTableAndContents(startupCode, modules, encoding)
|
buildTableAndContents(startupCode, modules, encoding)
|
||||||
);
|
).then(() => log('Done writing unbundle output'));
|
||||||
|
|
||||||
writeUnbundle.then(() => log('Done writing unbundle output'));
|
return Promise.all([
|
||||||
|
writeUnbundle,
|
||||||
return Promise.all([writeUnbundle, writeSourceMap(sourcemapOutput, '', log)]);
|
writeSourceMap(
|
||||||
|
sourcemapOutput,
|
||||||
|
buildUnbundleSourcemap(bundle),
|
||||||
|
log,
|
||||||
|
),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* global Buffer: true */
|
/* global Buffer: true */
|
||||||
|
@ -60,13 +65,16 @@ function writeBuffers(stream, buffers) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleToBuffer = ({name, code}, encoding) => ({
|
function moduleToBuffer(name, code, encoding) {
|
||||||
name,
|
return {
|
||||||
buffer: Buffer.concat([
|
name,
|
||||||
Buffer(code, encoding),
|
linesCount: code.split('\n').length,
|
||||||
nullByteBuffer // create \0-terminated strings
|
buffer: Buffer.concat([
|
||||||
])
|
Buffer(code, encoding),
|
||||||
});
|
nullByteBuffer // create \0-terminated strings
|
||||||
|
])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function uInt32Buffer(n) {
|
function uInt32Buffer(n) {
|
||||||
const buffer = Buffer(4);
|
const buffer = Buffer(4);
|
||||||
|
@ -82,23 +90,28 @@ function buildModuleTable(buffers) {
|
||||||
// entry:
|
// entry:
|
||||||
// - module_id: NUL terminated utf8 string
|
// - module_id: NUL terminated utf8 string
|
||||||
// - module_offset: uint_32 offset into the module string
|
// - module_offset: uint_32 offset into the module string
|
||||||
// - module_length: uint_32 length of the module string, including terminating NUL byte
|
// - module_line: uint_32 line on which module starts on the bundle
|
||||||
|
|
||||||
const numBuffers = buffers.length;
|
const numBuffers = buffers.length;
|
||||||
|
|
||||||
const tableLengthBuffer = uInt32Buffer(0);
|
const tableLengthBuffer = uInt32Buffer(0);
|
||||||
let tableLength = 4; // the table length itself, 4 == tableLengthBuffer.length
|
let tableLength = 4; // the table length itself, 4 == tableLengthBuffer.length
|
||||||
let currentOffset = 0;
|
let currentOffset = 0;
|
||||||
|
let currentLine = 1;
|
||||||
|
|
||||||
const offsetTable = [tableLengthBuffer];
|
const offsetTable = [tableLengthBuffer];
|
||||||
for (let i = 0; i < numBuffers; i++) {
|
for (let i = 0; i < numBuffers; i++) {
|
||||||
const {name, buffer: {length}} = buffers[i];
|
const {name, linesCount, buffer: {length}} = buffers[i];
|
||||||
|
|
||||||
const entry = Buffer.concat([
|
const entry = Buffer.concat([
|
||||||
Buffer(i === 0 ? MAGIC_STARTUP_MODULE_ID : name, 'utf8'),
|
Buffer(i === 0 ? MAGIC_STARTUP_MODULE_ID : name, 'utf8'),
|
||||||
nullByteBuffer,
|
nullByteBuffer,
|
||||||
uInt32Buffer(currentOffset),
|
uInt32Buffer(currentOffset),
|
||||||
uInt32Buffer(length)
|
uInt32Buffer(currentLine),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
currentLine += linesCount - 1;
|
||||||
|
|
||||||
currentOffset += length;
|
currentOffset += length;
|
||||||
tableLength += entry.length;
|
tableLength += entry.length;
|
||||||
offsetTable.push(entry);
|
offsetTable.push(entry);
|
||||||
|
@ -110,14 +123,22 @@ function buildModuleTable(buffers) {
|
||||||
|
|
||||||
function buildModuleBuffers(startupCode, modules, encoding) {
|
function buildModuleBuffers(startupCode, modules, encoding) {
|
||||||
return (
|
return (
|
||||||
[moduleToBuffer({name: '', code: startupCode}, encoding)]
|
[moduleToBuffer('', startupCode, encoding, true)].concat(
|
||||||
.concat(modules.map(module => moduleToBuffer(module, encoding)))
|
modules.map(module =>
|
||||||
|
moduleToBuffer(
|
||||||
|
module.name,
|
||||||
|
module.code + '\n', // each module starts on a newline
|
||||||
|
encoding,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTableAndContents(startupCode, modules, encoding) {
|
function buildTableAndContents(startupCode, modules, encoding) {
|
||||||
const buffers = buildModuleBuffers(startupCode, modules, encoding);
|
const buffers = buildModuleBuffers(startupCode, modules, encoding);
|
||||||
const table = buildModuleTable(buffers, encoding);
|
const table = buildModuleTable(buffers, encoding);
|
||||||
|
|
||||||
return [fileHeader, table].concat(buffers.map(({buffer}) => buffer));
|
return [fileHeader, table].concat(buffers.map(({buffer}) => buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const sourceMap = require('source-map');
|
||||||
|
const SourceMapConsumer = sourceMap.SourceMapConsumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the sourcemaps for any type of unbundle provided the Bundle that
|
||||||
|
* contains the modules reachable from the entry point.
|
||||||
|
*
|
||||||
|
* The generated sourcemaps correspond to a regular bundle on which each module
|
||||||
|
* starts on a new line. Depending on the type of unbundle you're using, you
|
||||||
|
* will have to pipe the line number to native and use it when injecting the
|
||||||
|
* module's code into JSC. This way, we'll trick JSC to believe all the code is
|
||||||
|
* on a single big regular bundle where as it could be on an indexed bundle or
|
||||||
|
* as sparsed assets.
|
||||||
|
*/
|
||||||
|
function buildUnbundleSourcemap(bundle) {
|
||||||
|
const generator = new sourceMap.SourceMapGenerator({});
|
||||||
|
const nonPolyfillModules = bundle.getModules().filter(module =>
|
||||||
|
!module.polyfill
|
||||||
|
);
|
||||||
|
|
||||||
|
let offset = 1;
|
||||||
|
nonPolyfillModules.forEach(module => {
|
||||||
|
if (module.map) { // assets have no sourcemap
|
||||||
|
const consumer = new SourceMapConsumer(module.map);
|
||||||
|
consumer.eachMapping(mapping => {
|
||||||
|
generator.addMapping({
|
||||||
|
original: {
|
||||||
|
line: mapping.originalLine,
|
||||||
|
column: mapping.originalColumn,
|
||||||
|
},
|
||||||
|
generated: {
|
||||||
|
line: mapping.generatedLine + offset,
|
||||||
|
column: mapping.generatedColumn,
|
||||||
|
},
|
||||||
|
source: module.sourcePath,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
generator.setSourceContent(module.sourcePath, module.sourceCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some modules span more than 1 line
|
||||||
|
offset += module.code.split('\n').length;
|
||||||
|
});
|
||||||
|
|
||||||
|
return generator.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = buildUnbundleSourcemap;
|
|
@ -16,7 +16,7 @@ function writeSourcemap(fileName, contents, log) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
log('Writing sourcemap output to:', fileName);
|
log('Writing sourcemap output to:', fileName);
|
||||||
const writeMap = writeFile(fileName, '', null);
|
const writeMap = writeFile(fileName, contents, null);
|
||||||
writeMap.then(() => log('Done writing sourcemap output'));
|
writeMap.then(() => log('Done writing sourcemap output'));
|
||||||
return writeMap;
|
return writeMap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,6 @@ const crypto = require('crypto');
|
||||||
|
|
||||||
const SOURCEMAPPING_URL = '\n\/\/# sourceMappingURL=';
|
const SOURCEMAPPING_URL = '\n\/\/# sourceMappingURL=';
|
||||||
|
|
||||||
const getCode = x => x.code;
|
|
||||||
const getNameAndCode = ({name, code}) => ({name, code});
|
|
||||||
|
|
||||||
class Bundle extends BundleBase {
|
class Bundle extends BundleBase {
|
||||||
constructor({sourceMapUrl, minify} = {}) {
|
constructor({sourceMapUrl, minify} = {}) {
|
||||||
super();
|
super();
|
||||||
|
@ -40,6 +37,7 @@ class Bundle extends BundleBase {
|
||||||
map: moduleTransport.map,
|
map: moduleTransport.map,
|
||||||
meta: moduleTransport.meta,
|
meta: moduleTransport.meta,
|
||||||
minify: this._minify,
|
minify: this._minify,
|
||||||
|
polyfill: module.isPolyfill(),
|
||||||
}).then(({code, map}) => {
|
}).then(({code, map}) => {
|
||||||
// If we get a map from the transformer we'll switch to a mode
|
// If we get a map from the transformer we'll switch to a mode
|
||||||
// were we're combining the source maps as opposed to
|
// were we're combining the source maps as opposed to
|
||||||
|
@ -113,20 +111,21 @@ class Bundle extends BundleBase {
|
||||||
const modules =
|
const modules =
|
||||||
allModules
|
allModules
|
||||||
.splice(prependedModules, allModules.length - requireCalls - prependedModules);
|
.splice(prependedModules, allModules.length - requireCalls - prependedModules);
|
||||||
const startupCode = allModules.map(getCode).join('\n');
|
const startupCode = allModules.map(({code}) => code).join('\n');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
startupCode,
|
startupCode,
|
||||||
modules: modules.map(getNameAndCode)
|
modules: modules.map(({name, code, polyfill}) =>
|
||||||
|
({name, code, polyfill})
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* I found a neat trick in the sourcemap spec that makes it easy
|
* Combine each of the sourcemaps multiple modules have into a single big
|
||||||
* to concat sourcemaps. The `sections` field allows us to combine
|
* one. This works well thanks to a neat trick defined on the sourcemap spec
|
||||||
* the sourcemap easily by adding an offset. Tested on chrome.
|
* that makes use of of the `sections` field to combine sourcemaps by adding
|
||||||
* Seems like it's not yet in Firefox but that should be fine for
|
* an offset. This is supported only by Chrome for now.
|
||||||
* now.
|
|
||||||
*/
|
*/
|
||||||
_getCombinedSourceMaps(options) {
|
_getCombinedSourceMaps(options) {
|
||||||
const result = {
|
const result = {
|
||||||
|
|
|
@ -123,7 +123,7 @@ describe('Bundle', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const promise = Promise.all(
|
const promise = Promise.all(
|
||||||
moduleTransports.map(m => bundle.addModule(resolver, null, null, m)))
|
moduleTransports.map(m => bundle.addModule(resolver, null, {isPolyfill: () => false}, m)))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
expect(bundle.getModules())
|
expect(bundle.getModules())
|
||||||
.toEqual(moduleTransports);
|
.toEqual(moduleTransports);
|
||||||
|
@ -375,12 +375,19 @@ function resolverFor(code, map) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addModule({bundle, code, sourceCode, sourcePath, map, virtual}) {
|
function addModule({bundle, code, sourceCode, sourcePath, map, virtual, polyfill}) {
|
||||||
return bundle.addModule(
|
return bundle.addModule(
|
||||||
resolverFor(code, map),
|
resolverFor(code, map),
|
||||||
null,
|
null,
|
||||||
null,
|
{isPolyfill: () => polyfill},
|
||||||
createModuleTransport({code, sourceCode, sourcePath, map, virtual})
|
createModuleTransport({
|
||||||
|
code,
|
||||||
|
sourceCode,
|
||||||
|
sourcePath,
|
||||||
|
map,
|
||||||
|
virtual,
|
||||||
|
polyfill,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,7 @@ describe('Bundler', function() {
|
||||||
transform: {
|
transform: {
|
||||||
dev: true,
|
dev: true,
|
||||||
hot: false,
|
hot: false,
|
||||||
|
generateSourceMaps: false,
|
||||||
projectRoots,
|
projectRoots,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -230,8 +230,9 @@ class Bundler {
|
||||||
platform,
|
platform,
|
||||||
moduleSystemDeps = [],
|
moduleSystemDeps = [],
|
||||||
hot,
|
hot,
|
||||||
|
unbundle,
|
||||||
entryModuleOnly,
|
entryModuleOnly,
|
||||||
resolutionResponse
|
resolutionResponse,
|
||||||
}) {
|
}) {
|
||||||
const onResolutionResponse = response => {
|
const onResolutionResponse = response => {
|
||||||
bundle.setMainModuleId(response.mainModuleId);
|
bundle.setMainModuleId(response.mainModuleId);
|
||||||
|
@ -265,6 +266,7 @@ class Bundler {
|
||||||
platform,
|
platform,
|
||||||
bundle,
|
bundle,
|
||||||
hot,
|
hot,
|
||||||
|
unbundle,
|
||||||
resolutionResponse,
|
resolutionResponse,
|
||||||
onResolutionResponse,
|
onResolutionResponse,
|
||||||
finalizeBundle,
|
finalizeBundle,
|
||||||
|
@ -316,6 +318,7 @@ class Bundler {
|
||||||
platform,
|
platform,
|
||||||
bundle,
|
bundle,
|
||||||
hot,
|
hot,
|
||||||
|
unbundle,
|
||||||
resolutionResponse,
|
resolutionResponse,
|
||||||
onResolutionResponse = noop,
|
onResolutionResponse = noop,
|
||||||
onModuleTransformed = noop,
|
onModuleTransformed = noop,
|
||||||
|
@ -336,8 +339,15 @@ class Bundler {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
resolutionResponse = this.getDependencies(
|
resolutionResponse = this.getDependencies({
|
||||||
{entryFile, dev, platform, hot, onProgess, minify});
|
entryFile,
|
||||||
|
dev,
|
||||||
|
platform,
|
||||||
|
hot,
|
||||||
|
onProgess,
|
||||||
|
minify,
|
||||||
|
generateSourceMaps: unbundle,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve(resolutionResponse).then(response => {
|
return Promise.resolve(resolutionResponse).then(response => {
|
||||||
|
@ -391,10 +401,18 @@ class Bundler {
|
||||||
minify = !dev,
|
minify = !dev,
|
||||||
hot = false,
|
hot = false,
|
||||||
recursive = true,
|
recursive = true,
|
||||||
|
generateSourceMaps = false,
|
||||||
onProgess,
|
onProgess,
|
||||||
}) {
|
}) {
|
||||||
return this.getTransformOptions(
|
return this.getTransformOptions(
|
||||||
entryFile, {dev, platform, hot, projectRoots: this._projectRoots}
|
entryFile,
|
||||||
|
{
|
||||||
|
dev,
|
||||||
|
platform,
|
||||||
|
hot,
|
||||||
|
generateSourceMaps,
|
||||||
|
projectRoots: this._projectRoots,
|
||||||
|
},
|
||||||
).then(transformSpecificOptions => {
|
).then(transformSpecificOptions => {
|
||||||
const transformOptions = {
|
const transformOptions = {
|
||||||
minify,
|
minify,
|
||||||
|
|
|
@ -261,6 +261,10 @@ class Resolver {
|
||||||
: result;
|
: result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
minifyModule({path, code, map}) {
|
||||||
|
return this._minifyCode(path, code, map);
|
||||||
|
}
|
||||||
|
|
||||||
getDebugInfo() {
|
getDebugInfo() {
|
||||||
return this._depGraph.getDebugInfo();
|
return this._depGraph.getDebugInfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ function ModuleTransport(data) {
|
||||||
|
|
||||||
this.virtual = data.virtual;
|
this.virtual = data.virtual;
|
||||||
this.meta = data.meta;
|
this.meta = data.meta;
|
||||||
|
this.polyfill = data.polyfill;
|
||||||
this.map = data.map;
|
this.map = data.map;
|
||||||
|
|
||||||
Object.freeze(this);
|
Object.freeze(this);
|
||||||
|
|
Loading…
Reference in New Issue