Skip to content

Commit

Permalink
feat(cli): support outer dependencies collect
Browse files Browse the repository at this point in the history
nowaday, loader can use .dependecy fn to add outer dependencies, while this kind of deps changed,
it's parent module will be compiled

re #8
  • Loading branch information
Genuifx committed Jul 9, 2019
1 parent c73d907 commit 19dfb0d
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 56 deletions.
128 changes: 83 additions & 45 deletions packages/wxa-cli/src/builder.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {readFile, applyPlugins, isFile, getHash} from './utils';
import {readFile, applyPlugins, isFile, getHash, promiseSerial} from './utils';
import path from 'path';
import fs from 'fs';
import chokidar from 'chokidar';
Expand Down Expand Up @@ -68,16 +68,22 @@ class Builder {
}

filterModule(indexedMap) {
let ret = [];
let ret = new Set();
indexedMap.forEach((dep)=>{
if (
!/src\/_wxa/.test(dep.src)
) {
ret.push(dep.src);
ret.add(dep.src);
}

if (dep.outerDependencies) {
// logger.info('Outer Dependencies ', dep.outerDependencies);
// if an outer dependencies is change, just compile the module is depended.
dep.outerDependencies.forEach((file)=>ret.add(`${file}`));
}
});

return ret;
return Array.from(ret);
}

watch(cmd) {
Expand Down Expand Up @@ -106,54 +112,35 @@ class Builder {
logger.warn('change', filepath);
debug('WATCH file changed %s', filepath);
let mdl = this.schedule.$indexOfModule.get(filepath);
let isChange = true;
debug('Changed Module %O', mdl);
// module with code;
if (!mdl.isFile) {
let hash = getHash(filepath);
isChange = mdl.hash !== hash;
debug('OLD HASH %s, NEW HASH %s', mdl.hash, hash);
}

if (isChange) {
mdl.color = color.CHANGED;
mdl.content = void(0);
mdl.code = void(0);

let changedDeps;
try {
this.schedule.$depPending.push(mdl);
if (mdl.childNodes && mdl.childNodes.size) this.walkChildNodesTreeAndMark(mdl);
await this.hooks.rebuildModule.promise(this.schedule, mdl);

changedDeps = await this.schedule.$doDPA();

let map = new Map(changedDeps.map((mdl)=>[mdl.src, mdl]));

await this.optimizeAndGenerate(map, this.schedule.appConfigs, cmd);
} catch (e) {
logger.error('编译失败', e);
}
if (mdl == null) {
// maybe outer dependencies.
let defer = [];

let newFiles = this.filterModule(this.schedule.$indexOfModule);
let unlinkFiles = files.filter((oldFilePath)=>!~newFiles.indexOf(oldFilePath));
let addFiles = newFiles.filter((filePath)=>!~files.indexOf(filePath));
this.schedule.$indexOfModule.forEach((mdl)=>{
if (!mdl.outerDependencies || !mdl.outerDependencies.size || !mdl.outerDependencies.has(filepath)) return;

// unwatch deleted file add watch to new Files;
debug('addFiles %O, unlinkFiles %O', addFiles, unlinkFiles);
if (cmd.verbose) {
logger.info('Add Files', addFiles, ' COUNT:', addFiles.length);
logger.info('Unwatch Files', unlinkFiles, ' COUNT:', unlinkFiles.length);
}
defer.push(async ()=>{
try {
this.schedule.$depPending.push(mdl);
if (mdl.childNodes && mdl.childNodes.size) this.walkChildNodesTreeAndMark(mdl);

if (addFiles && addFiles.length) this.watcher.add(addFiles);
if (unlinkFiles && unlinkFiles.length) this.watcher.unwatch(unlinkFiles);
await this.hooks.rebuildModule.promise(this.schedule, mdl);

files = newFiles;
let changedDeps = await this.schedule.$doDPA();
let map = new Map(changedDeps.map((mdl)=>[mdl.src, mdl]));
await this.optimizeAndGenerate(map, this.schedule.appConfigs, cmd);
} catch (e) {
logger.error('编译失败', e);
}
});
});

await this.hooks.finishRebuildModule.promise(this.schedule, mdl);
await promiseSerial(defer);
} else {
logger.info(`文件无变化(${mdl.hash})`);
// normol deps changed
let {isChange, newFiles} = await this.compileChangedFile({filepath, mdl, files, cmd}) || {};
if (isChange) files = newFiles;
}

this.isDoingUpade = false;
Expand Down Expand Up @@ -185,6 +172,57 @@ class Builder {
});
}

async compileChangedFile({filepath, mdl, files, cmd}) {
let isChange = true;
debug('Changed Module %O', mdl);
// module with code;
if (!mdl.isFile) {
let hash = getHash(filepath);
isChange = mdl.hash !== hash;
debug('OLD HASH %s, NEW HASH %s', mdl.hash, hash);
}

if (isChange) {
mdl.color = color.CHANGED;
mdl.content = void(0);
mdl.code = void(0);

let changedDeps;
try {
this.schedule.$depPending.push(mdl);
if (mdl.childNodes && mdl.childNodes.size) this.walkChildNodesTreeAndMark(mdl);

await this.hooks.rebuildModule.promise(this.schedule, mdl);

changedDeps = await this.schedule.$doDPA();
let map = new Map(changedDeps.map((mdl)=>[mdl.src, mdl]));
await this.optimizeAndGenerate(map, this.schedule.appConfigs, cmd);
} catch (e) {
logger.error('编译失败', e);
}

let newFiles = this.filterModule(this.schedule.$indexOfModule);
let unlinkFiles = files.filter((oldFilePath)=>!~newFiles.indexOf(oldFilePath));
let addFiles = newFiles.filter((filePath)=>!~files.indexOf(filePath));

// unwatch deleted file add watch to new Files;
debug('addFiles %O, unlinkFiles %O', addFiles, unlinkFiles);
if (cmd.verbose) {
logger.info('Add Files', addFiles, ' COUNT:', addFiles.length);
logger.info('Unwatch Files', unlinkFiles, ' COUNT:', unlinkFiles.length);
}

if (addFiles && addFiles.length) this.watcher.add(addFiles);
if (unlinkFiles && unlinkFiles.length) this.watcher.unwatch(unlinkFiles);

await this.hooks.finishRebuildModule.promise(this.schedule, mdl);

return {isChange, newFiles};
} else {
logger.info(`文件无变化(${mdl.hash})`);
}
}

async build(cmd) {
if (cmd.verbose) logger.info('WxaConfigs', this.wxaConfigs);

Expand Down
13 changes: 5 additions & 8 deletions packages/wxa-cli/src/helpers/dependencyResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ class DependencyResolver {
if (pret.isURI || pret.isDynamic || pret.isBase64) return {pret, source, lib};
// 处理无后缀情况
// ext = path.extname(source);
if (!isFile(source) && pret.isNodeModule) {
ext = this.$findNodeModuleEntryFile(lib, source);

if (ext == null) throw new Error('找不到文件 '+lib);
} else if (!isFile(source) && !pret.isWXALib) {
if (!isFile(source) && !pret.isWXALib) {
// not support resolve extension.
if (!needFindExt) throw new Error('文件不存在');

Expand All @@ -41,11 +37,12 @@ class DependencyResolver {
// 非完整后缀的路径
if (isFile(source+this.meta.wxaExt)) ext = '.js'; // .wxa的文件转js
else if (pext) ext = pext;
else if (isDir(source) && isFile(source+path.sep+'index.js')) ext = path.sep+'index.js';
else {
else if (pret.isNodeModule) {
ext = this.$findNodeModuleEntryFile(lib, source);

if (ext == null) throw new Error('找不到文件 '+lib);
} else if (isDir(source) && isFile(source+path.sep+'index.js')) ext = path.sep+'index.js';
else {
throw new Error('找不到文件 '+lib);
}
} else {
ext = '';
Expand Down
4 changes: 2 additions & 2 deletions packages/wxa-cli/src/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class CompilerLoader {
}, Promise.resolve([]));
}

async compile(mdl) {
async compile(mdl, compilation) {
let tasks = [];

let fn = async (task, mdl)=>{
Expand All @@ -143,7 +143,7 @@ class CompilerLoader {
if (test.test(mdl.src)) {
debug('loader is working %O, dep %O', loader, mdl);
try {
let {code, ...rest} = await loader.parse(mdl, cmdOptions);
let {code, ...rest} = await loader.parse(mdl, cmdOptions, compilation);

// Todo: Multi loader with one string
mdl.code = code;
Expand Down
10 changes: 9 additions & 1 deletion packages/wxa-cli/src/schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class Schedule {
this.perf.markStart(relativeSrc);
this.hooks.buildModule.call(dep);
// loader: use custom compiler to load resource.
await this.loader.compile(dep);
await this.loader.compile(dep, this);

this.perf.markEnd(relativeSrc);

Expand Down Expand Up @@ -294,6 +294,14 @@ class Schedule {
isPlugin: dep.pret.isPlugin,
reference: new Map([[mdl.src, mdl]]),
output: new Set([dep.meta.outputPath]),
outerDependencies: new Set(),
dependency: function(file) {
// let DR = new DependencyResolver(scheduler.wxaConfigs.resolve, scheduler.meta);
// let {source} = DR.resolveDep(file, this);

// debugger;
this.outerDependencies.add(file);
},
};


Expand Down
6 changes: 6 additions & 0 deletions packages/wxa-cli/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,9 @@ export function getHash(filepath) {
export function getHashWithString(content) {
return content == null ? Date.now() : crypto.createHash('md5').update(content).digest('hex');
}

export function promiseSerial(funs) {
return funs.reduce((promise, fun)=>{
return promise.then((result)=>fun().then(Array.prototype.concat.bind(result)));
}, Promise.resolve([]));
}

0 comments on commit 19dfb0d

Please sign in to comment.