From 453a861302bab052a776efa66cee6f67433f90cd Mon Sep 17 00:00:00 2001 From: sunnylqm Date: Sun, 14 Apr 2019 13:31:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=BC=E5=AE=B90.59=E7=9A=84bundle=E5=91=BD?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- local-cli/src/bundle.js | 250 +++++++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 108 deletions(-) diff --git a/local-cli/src/bundle.js b/local-cli/src/bundle.js index 6b77cee..e018d60 100644 --- a/local-cli/src/bundle.js +++ b/local-cli/src/bundle.js @@ -5,30 +5,30 @@ import * as path from 'path'; import { mkdir as mkdirRecurisve } from 'mkdir-recursive'; import rmdirRecursive from 'rimraf'; -import { - getRNVersion, - translateOptions, -} from './utils'; +import { getRNVersion, translateOptions } from './utils'; import * as fs from 'fs'; -import {ZipFile} from 'yazl'; -import {open as openZipFile} from 'yauzl'; +import { ZipFile } from 'yazl'; +import { open as openZipFile } from 'yauzl'; // import {diff} from 'node-bsdiff'; import { question } from './utils'; -import {checkPlatform} from './app'; +import { checkPlatform } from './app'; import crypto from 'crypto'; +import minimist from 'minimist'; var diff; try { var bsdiff = require('node-bsdiff'); diff = typeof bsdiff != 'function' ? bsdiff.diff : bsdiff; -} catch(e) { +} catch (e) { diff = function() { - console.warn('This function needs "node-bsdiff". Please run "npm i node-bsdiff -S" from your project directory first!'); - throw new Error('This function needs module "node-bsdiff". Please install it first.') - } + console.warn( + 'This function needs "node-bsdiff". Please run "npm i node-bsdiff -S" from your project directory first!', + ); + throw new Error('This function needs module "node-bsdiff". Please install it first.'); + }; } -function mkdir(dir){ +function mkdir(dir) { return new Promise((resolve, reject) => { mkdirRecurisve(dir, err => { if (err) { @@ -52,28 +52,28 @@ function rmdir(dir) { }); } -async function pack(dir, output){ +async function pack(dir, output) { await mkdir(path.dirname(output)); await new Promise((resolve, reject) => { var zipfile = new ZipFile(); - function addDirectory(root, rel){ + function addDirectory(root, rel) { if (rel) { zipfile.addEmptyDirectory(rel); } const childs = fs.readdirSync(root); for (const name of childs) { - if (name === '.' || name === '..'){ + if (name === '.' || name === '..') { continue; } const fullPath = path.join(root, name); const stat = fs.statSync(fullPath); if (stat.isFile()) { //console.log('adding: ' + rel+name); - zipfile.addFile(fullPath, rel+name); + zipfile.addFile(fullPath, rel + name); } else if (stat.isDirectory()) { //console.log('adding: ' + rel+name+'/'); - addDirectory(fullPath, rel+name+'/'); + addDirectory(fullPath, rel + name + '/'); } } } @@ -81,10 +81,9 @@ async function pack(dir, output){ addDirectory(dir, ''); zipfile.outputStream.on('error', err => reject(err)); - zipfile.outputStream.pipe(fs.createWriteStream(output)) - .on("close", function() { - resolve(); - }); + zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', function() { + resolve(); + }); zipfile.end(); }); console.log('Bundled saved to: ' + output); @@ -101,18 +100,13 @@ function readEntire(entry, zipFile) { end() { resolve(Buffer.concat(buffers)); }, - prependListener() { - - }, - on() { - }, - once() { - }, - emit() { - }, - }) + prependListener() {}, + on() {}, + once() {}, + emit() {}, + }); }); - }) + }); } function basename(fn) { @@ -136,7 +130,7 @@ async function diffFromPPK(origin, next, output) { if (entry.fileName === 'index.bundlejs') { // This is source. - return readEntire(entry, zipFile).then(v=>originSource = v); + return readEntire(entry, zipFile).then(v => (originSource = v)); } } }); @@ -147,12 +141,13 @@ async function diffFromPPK(origin, next, output) { var zipfile = new ZipFile(); - const writePromise = new Promise((resolve, reject)=>{ - zipfile.outputStream.on('error', err => {throw err;}); - zipfile.outputStream.pipe(fs.createWriteStream(output)) - .on("close", function() { - resolve(); - }); + const writePromise = new Promise((resolve, reject) => { + zipfile.outputStream.on('error', err => { + throw err; + }); + zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', function() { + resolve(); + }); }); const addedEntry = {}; @@ -181,7 +176,7 @@ async function diffFromPPK(origin, next, output) { } } else if (entry.fileName === 'index.bundlejs') { //console.log('Found bundle'); - return readEntire(entry, nextZipfile).then( newSource => { + return readEntire(entry, nextZipfile).then(newSource => { //console.log('Begin diff'); zipfile.addBuffer(diff(originSource, newSource), 'index.bundlejs.patch'); //console.log('End diff'); @@ -195,7 +190,7 @@ async function diffFromPPK(origin, next, output) { } // If moved from other place - if (originMap[entry.crc32]){ + if (originMap[entry.crc32]) { const base = basename(entry.fileName); if (!originEntries[base]) { addEntry(base); @@ -207,9 +202,9 @@ async function diffFromPPK(origin, next, output) { // New file. addEntry(basename(entry.fileName)); - return new Promise((resolve, reject)=>{ + return new Promise((resolve, reject) => { nextZipfile.openReadStream(entry, function(err, readStream) { - if (err){ + if (err) { return reject(err); } zipfile.addReadStream(readStream, entry.fileName); @@ -218,7 +213,7 @@ async function diffFromPPK(origin, next, output) { resolve(); }); }); - }) + }); } }); @@ -226,18 +221,18 @@ async function diffFromPPK(origin, next, output) { for (var k in originEntries) { if (!newEntries[k]) { - console.log('Delete '+k); + console.log('Delete ' + k); deletes[k] = 1; } } //console.log({copies, deletes}); - zipfile.addBuffer(new Buffer(JSON.stringify({copies, deletes})), '__diff.json'); + zipfile.addBuffer(new Buffer(JSON.stringify({ copies, deletes })), '__diff.json'); zipfile.end(); await writePromise; } -async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = v=>v) { +async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = v => v) { await mkdir(path.dirname(output)); const originEntries = {}; @@ -259,7 +254,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform if (fn === originBundleName) { // This is source. - return readEntire(entry, zipFile).then(v=>originSource = v); + return readEntire(entry, zipFile).then(v => (originSource = v)); } } }); @@ -270,12 +265,13 @@ async function diffFromPackage(origin, next, output, originBundleName, transform var zipfile = new ZipFile(); - const writePromise = new Promise((resolve, reject)=>{ - zipfile.outputStream.on('error', err => {throw err;}); - zipfile.outputStream.pipe(fs.createWriteStream(output)) - .on("close", function() { - resolve(); - }); + const writePromise = new Promise((resolve, reject) => { + zipfile.outputStream.on('error', err => { + throw err; + }); + zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', function() { + resolve(); + }); }); await enumZipEntries(next, (entry, nextZipfile) => { @@ -284,7 +280,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform zipfile.addEmptyDirectory(entry.fileName); } else if (entry.fileName === 'index.bundlejs') { //console.log('Found bundle'); - return readEntire(entry, nextZipfile).then( newSource => { + return readEntire(entry, nextZipfile).then(newSource => { //console.log('Begin diff'); zipfile.addBuffer(diff(originSource, newSource), 'index.bundlejs.patch'); //console.log('End diff'); @@ -296,14 +292,14 @@ async function diffFromPackage(origin, next, output, originBundleName, transform return; } // If moved from other place - if (originMap[entry.crc32]){ + if (originMap[entry.crc32]) { copies[entry.fileName] = originMap[entry.crc32]; return; } - return new Promise((resolve, reject)=>{ + return new Promise((resolve, reject) => { nextZipfile.openReadStream(entry, function(err, readStream) { - if (err){ + if (err) { return reject(err); } zipfile.addReadStream(readStream, entry.fileName); @@ -312,18 +308,18 @@ async function diffFromPackage(origin, next, output, originBundleName, transform resolve(); }); }); - }) + }); } }); - zipfile.addBuffer(new Buffer(JSON.stringify({copies})), '__diff.json'); + zipfile.addBuffer(new Buffer(JSON.stringify({ copies })), '__diff.json'); zipfile.end(); await writePromise; } function enumZipEntries(zipFn, callback) { return new Promise((resolve, reject) => { - openZipFile(zipFn, {lazyEntries:true}, (err, zipfile) => { + openZipFile(zipFn, { lazyEntries: true }, (err, zipfile) => { if (err) { return reject(err); } @@ -331,7 +327,7 @@ function enumZipEntries(zipFn, callback) { zipfile.on('error', reject); zipfile.on('entry', entry => { const result = callback(entry, zipfile); - if (result && typeof(result.then) === 'function') { + if (result && typeof result.then === 'function') { result.then(() => zipfile.readEntry()); } else { zipfile.readEntry(); @@ -343,16 +339,13 @@ function enumZipEntries(zipFn, callback) { } export const commands = { - bundle: async function({options}){ - const platform = checkPlatform(options.platform || await question('Platform(ios/android):')); + bundle: async function({ options }) { + const platform = checkPlatform(options.platform || (await question('Platform(ios/android):'))); - let { - entryFile, - intermediaDir, - output, - dev, - verbose - } = translateOptions({...options, platform}); + let { entryFile, intermediaDir, output, dev, verbose } = translateOptions({ + ...options, + platform, + }); const realIntermedia = path.resolve(intermediaDir); @@ -368,7 +361,7 @@ export const commands = { await rmdir(realIntermedia); await mkdir(realIntermedia); - + if (major === 0) { if (minor >= 56) { require('metro-babel-register'); @@ -390,9 +383,7 @@ export const commands = { // This line fix issue #11 require(path.resolve('node_modules/react-native/local-cli/cli')); - const Config = require(path.resolve('node_modules/react-native/local-cli/util/Config')); - const bundle = require(path.resolve('node_modules/react-native/local-cli/bundle/bundle')); - let defaultConfig; + let Config, defaultConfig, bundle; if (major === 0) { if (minor >= 49) { @@ -403,7 +394,38 @@ export const commands = { } if (major === 0) { - if (minor >= 57) { + if (minor >= 0.59) { + Config = require(path.resolve('node_modules/@react-native-community/cli/build/tools/loadMetroConfig')); + bundle = require(path.resolve('node_modules/@react-native-community/cli/build/commands/bundle/bundle')).default; + } else { + Config = require(path.resolve('node_modules/react-native/local-cli/util/Config')); + bundle = require(path.resolve('node_modules/react-native/local-cli/bundle/bundle')); + } + if (minor >= 59) { + // https://github.com/react-native-community/cli/blob/1.x/packages/cli/src/cliEntry.js#L170-L202 + const options = minimist(process.argv.slice(2)); + + const root = options.projectRoot ? path.resolve(options.projectRoot) : process.cwd(); + + const reactNativePath = options.reactNativePath + ? path.resolve(options.reactNativePath) + : (() => { + try { + return path.dirname( + require.resolve('react-native/package.json', { + paths: [root], + }), + ); + } catch (_ignored) { + throw new Error('Unable to find React Native files. Please use --reactNativePath to specify the path.'); + } + })(); + + defaultConfig = { + reactNativePath, + root, + }; + } else if (minor >= 57) { // https://github.com/facebook/react-native/commit/a32620dc3b7a0ebd53feeaf7794051705d80f49e#diff-75692fe55c8b1a7c05f4264301342167L101 // defaultConfig = Config.load(); const { configPromise } = require(path.resolve('node_modules/react-native/local-cli/core')); @@ -411,26 +433,32 @@ export const commands = { } else if (minor >= 45) { defaultConfig = Config.findOptional(path.resolve('.')); } else if (minor >= 42) { - defaultConfig= Config.get( + defaultConfig = Config.get( path.resolve('node_modules/react-native/local-cli'), require(path.resolve('node_modules/react-native/local-cli/core/default.config')), - path.resolve('node_modules/react-native/packager/rn-cli.config.js')); + path.resolve('node_modules/react-native/packager/rn-cli.config.js'), + ); } else if (minor >= 33) { - defaultConfig= Config.get( + defaultConfig = Config.get( path.resolve('node_modules/react-native/local-cli'), require(path.resolve('node_modules/react-native/local-cli/default.config')), - path.resolve('node_modules/react-native/packager/rn-cli.config.js')); + path.resolve('node_modules/react-native/packager/rn-cli.config.js'), + ); } else { - defaultConfig= Config.get(path.resolve('node_modules/react-native/local-cli'), require(path.resolve('node_modules/react-native/local-cli/default.config'))); + defaultConfig = Config.get( + path.resolve('node_modules/react-native/local-cli'), + require(path.resolve('node_modules/react-native/local-cli/default.config')), + ); } } else { defaultConfig = Config.findOptional(path.resolve('.')); } + console; if (bundle.func) { - // React native after 0.31.0 + // React native >= 0.31.0 await bundle.func([], defaultConfig, { - entryFile : entryFile, + entryFile: entryFile, platform: platform, dev: !!dev, bundleOutput: `${realIntermedia}${path.sep}index.bundlejs`, @@ -439,21 +467,24 @@ export const commands = { bundleEncoding: 'utf8', }); } else { - // React native before 0.30.0 - await bundle([ - '--entry-file', - entryFile, - '--platform', - platform, - '--dev', - '' + !!dev, - '--bundle-output', - `${realIntermedia}${path.sep}index.bundlejs`, - '--assets-dest', - `${realIntermedia}`, - '--verbose', - '' + !!verbose, - ], defaultConfig); + // React native < 0.31.0 + await bundle( + [ + '--entry-file', + entryFile, + '--platform', + platform, + '--dev', + '' + !!dev, + '--bundle-output', + `${realIntermedia}${path.sep}index.bundlejs`, + '--assets-dest', + `${realIntermedia}`, + '--verbose', + '' + !!verbose, + ], + defaultConfig, + ); } console.log('Packing'); @@ -462,15 +493,18 @@ export const commands = { const v = await question('Would you like to publish it?(Y/N)'); if (v.toLowerCase() === 'y') { - await this.publish({args: [realOutput], options: { - platform, - }}) + await this.publish({ + args: [realOutput], + options: { + platform, + }, + }); } }, - async diff({args, options}) { + async diff({ args, options }) { const [origin, next] = args; - const {output} = options; + const { output } = options; const realOutput = output.replace(/\$\{time\}/g, '' + Date.now()); @@ -483,9 +517,9 @@ export const commands = { console.log(`${realOutput} generated.`); }, - async diffFromApk({args, options}) { + async diffFromApk({ args, options }) { const [origin, next] = args; - const {output} = options; + const { output } = options; const realOutput = output.replace(/\$\{time\}/g, '' + Date.now()); @@ -498,9 +532,9 @@ export const commands = { console.log(`${realOutput} generated.`); }, - async diffFromIpa({args, options}) { + async diffFromIpa({ args, options }) { const [origin, next] = args; - const {output} = options; + const { output } = options; const realOutput = output.replace(/\$\{time\}/g, '' + Date.now()); @@ -509,7 +543,7 @@ export const commands = { process.exit(1); } - await diffFromPackage(origin, next, realOutput, 'main.jsbundle', v=>{ + await diffFromPackage(origin, next, realOutput, 'main.jsbundle', v => { const m = /^Payload\/[^/]+\/(.+)$/.exec(v); return m && m[1]; });