diff --git a/packages/wepy-cli/src/compile-script.js b/packages/wepy-cli/src/compile-script.js
index 771427c19..a21554335 100644
--- a/packages/wepy-cli/src/compile-script.js
+++ b/packages/wepy-cli/src/compile-script.js
@@ -24,31 +24,44 @@ let appPath, npmPath, src, dist;
export default {
resolveDeps (code, type, opath) {
-
let params = cache.getParams();
let config = cache.getConfig();
let wpyExt = params.wpyExt;
- let npmInfo = opath.npm;
return code.replace(/require\(['"]([\w\d_\-\.\/@]+)['"]\)/ig, (match, lib) => {
+ let npmInfo = opath.npm;
+
if (lib === './_wepylogs.js') {
return match;
}
let resolved = lib;
-
let target = '', source = '', ext = '', needCopy = false;
if (config.output === 'ant' && lib === 'wepy') {
lib = 'wepy-ant';
}
- lib = resolve.resolveAlias(lib);
- if (path.isAbsolute(lib)) {
+ lib = resolve.resolveAlias(lib, opath);
+ if (lib === 'false') {
+ return `{}`
+ } else if (path.isAbsolute(lib)) {
source = lib;
target = util.getDistPath(source);
} else if (lib[0] === '.') { // require('./something'');
- source = path.join(opath.dir, lib); // e:/src/util
+ let resolvedLib;
+ if (npmInfo && npmInfo.pkg._activeFields.length) {
+ resolvedLib = resolve.resolveSelfFields(npmInfo.dir, npmInfo.pkg, path.join(path.relative(npmInfo.dir, opath.dir), lib));
+ }
+ if (resolvedLib) {
+ source = path.join(npmInfo.dir, resolvedLib);
+ lib = path.relative(opath.dir, source);
+ if (lib[0] !== '.') {
+ lib = './' + lib;
+ }
+ } else {
+ source = path.join(opath.dir, lib);
+ }
if (type === 'npm') {
target = path.join(npmPath, path.relative(npmInfo.modulePath, source));
needCopy = true;
@@ -61,6 +74,11 @@ export default {
lib.indexOf('/') === lib.length - 1 || // reqiore('a/b/something/')
(lib[0] === '@' && lib.indexOf('/') !== -1 && lib.lastIndexOf('/') === lib.indexOf('/')) // require('@abc/something')
) {
+ // require('stream') -> browsers: emitter->emitter-component;
+ if (npmInfo && npmInfo.pkg._activeFields.length) {
+ let resolvedLib = resolve.resolveSelfFields(npmInfo.dir, npmInfo.pkg, lib);
+ lib = resolvedLib ? resolvedLib : lib;
+ }
let mainFile = resolve.getMainFile(lib);
@@ -71,12 +89,19 @@ export default {
lib: lib,
dir: mainFile.dir,
modulePath: mainFile.modulePath,
- file: mainFile.file
+ file: mainFile.file,
+ pkg: mainFile.pkg
};
- source = path.join(mainFile.dir, mainFile.file);
- target = path.join(npmPath, lib, mainFile.file);
- lib += path.sep + mainFile.file;
+ let resolvedFile;
+ if (mainFile.pkg && mainFile.pkg._activeFields.length) {
+ resolvedFile = resolve.resolveSelfFields(mainFile.dir, mainFile.pkg, mainFile.file);
+ }
+ resolvedFile = resolvedFile ? resolvedFile : mainFile.file;
+ source = path.join(mainFile.dir, resolvedFile);
+ target = path.join(npmPath, lib, resolvedFile);
+
+ lib += path.sep + resolvedFile;
ext = '';
needCopy = true;
} else { // require('babel-runtime/regenerator')
diff --git a/packages/wepy-cli/src/compile-style.js b/packages/wepy-cli/src/compile-style.js
index 03022b52e..15a028e91 100644
--- a/packages/wepy-cli/src/compile-style.js
+++ b/packages/wepy-cli/src/compile-style.js
@@ -106,12 +106,14 @@ export default {
requires.forEach((r) => {
let comsrc = null;
isNPM = false;
- if (path.isAbsolute(r)) {
- if (path.extname(r) === '' && util.isFile(r + ext)) {
- comsrc = r + ext;
+ let lib = resolve.resolveAlias(r, opath);
+
+ if (path.isAbsolute(lib)) {
+ if (path.extname(lib) === '' && util.isFile(lib + ext)) {
+ comsrc = lib + ext;
}
} else {
- let lib = resolve.resolveAlias(r);
+ // let lib = resolve.resolveAlias(r, opath);
if (path.isAbsolute(lib)) {
comsrc = lib;
} else {
diff --git a/packages/wepy-cli/src/compile-wpy.js b/packages/wepy-cli/src/compile-wpy.js
index cd9d5e6c4..f63ac0b05 100644
--- a/packages/wepy-cli/src/compile-wpy.js
+++ b/packages/wepy-cli/src/compile-wpy.js
@@ -373,7 +373,7 @@ export default {
}
});
if (Object.keys(props).length) {
- rst.script.code =rst.script.code.replace(/[\s\r\n]components\s*=[\s\r\n]*/, (match, item, index) => {
+ rst.script.code = rst.script.code.replace(/[\s\r\n]components\s*=[\s\r\n]*/, (match, item, index) => {
return `$repeat = ${JSON.stringify($repeat)};\r\n$props = ${JSON.stringify(props)};\r\n$events = ${JSON.stringify(events)};\r\n${match}`;
});
}
@@ -471,6 +471,14 @@ export default {
} else {
requires.push(path.join(opath.dir, wpy.template.components[k]));
}
+
+ // 去重
+ // Example:
+ // components = {
+ // Count1: '../components/count',
+ // Count2: '../components/count'
+ // };
+ requires = util.unique(requires)
}
}
try {
diff --git a/packages/wepy-cli/src/compile.js b/packages/wepy-cli/src/compile.js
index ba1e52654..7ecf15d3a 100644
--- a/packages/wepy-cli/src/compile.js
+++ b/packages/wepy-cli/src/compile.js
@@ -50,7 +50,7 @@ export default {
reg = new RegExp('\\' + ext + '$');
if (!reg.test(importpath))
importpath = importpath + ext;
- let resolved = resolve.resolveAlias(importpath);
+ let resolved = resolve.resolveAlias(importpath, opath);
let compath;
if (path.isAbsolute(resolved)) {
compath = path.resolve(resolved);
@@ -166,6 +166,7 @@ export default {
util.error('没有检测到wepy.config.js文件, 请执行`wepy new demo`创建');
return false;
}
+
resolve.init(wepyrc.resolve || {});
loader.attach(resolve);
@@ -202,11 +203,17 @@ export default {
if (config.output === 'web') {
- wepyrc.web = wepyrc.web || {};
- wepyrc.web.dist = wepyrc.web.dist || 'web';
- wepyrc.web.src = wepyrc.web.src || 'src';
+ wepyrc.build = wepyrc.build || {};
+ wepyrc.build.web = wepyrc.build.web || {};
+ wepyrc.build.web.dist = wepyrc.build.web.dist || 'web';
+ wepyrc.build.web.src = wepyrc.build.web.src || 'src';
+ if (wepyrc.build.web.resolve)
+ wepyrc.resolve = Object.assign({}, wepyrc.resolve, wepyrc.build.web.resolve);
wepyrc.output = 'web';
+ resolve.init(wepyrc.resolve || {});
+ loader.attach(resolve);
+
if (!resolve.getPkg('wepy-web')) {
util.log('正在尝试安装缺失资源 wepy-web,请稍等。', '信息');
util.exec(`npm install wepy-web --save`).then(d => {
@@ -219,11 +226,17 @@ export default {
return false;
}
} else if (config.output === 'ant') {
- wepyrc.ant = wepyrc.ant || {};
- wepyrc.ant.dist = wepyrc.ant.dist || 'ant';
- wepyrc.ant.src = wepyrc.ant.src || 'src';
+ wepyrc.build = wepyrc.build || {};
+ wepyrc.build.ant = wepyrc.build.ant || {};
+ wepyrc.build.ant.dist = wepyrc.build.ant.dist || 'ant';
+ wepyrc.build.ant.src = wepyrc.build.ant.src || 'src';
+ if (wepyrc.build.ant.resolve)
+ wepyrc.resolve = Object.assign({}, wepyrc.resolve, wepyrc.build.ant.resolve);
wepyrc.output = 'ant';
+ resolve.init(wepyrc.resolve || {});
+ loader.attach(resolve);
+
if (!resolve.getPkg('wepy-ant')) {
util.log('正在尝试安装缺失资源 wepy-ant,请稍等。', '信息');
util.exec(`npm install wepy-ant --save`).then(d => {
@@ -236,6 +249,7 @@ export default {
return false;
}
}
+
return true;
},
@@ -393,4 +407,4 @@ export default {
});
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/wepy-cli/src/resolve.js b/packages/wepy-cli/src/resolve.js
index a9473799b..fd4d930f6 100644
--- a/packages/wepy-cli/src/resolve.js
+++ b/packages/wepy-cli/src/resolve.js
@@ -10,17 +10,65 @@
import path from 'path';
import util from './util';
+import cache from './cache'
+
+const DEFAULT_MODULES = ['node_modules'];
+const DEFAULT_ALIASFIELDS = ['wepy', 'weapp', 'browser'];
+const DEFAULT_MAINFIELDS = ['wepy', 'weapp', 'browser', 'module', 'main'];
export default {
init (config) {
- this.modules = config.modules || ['node_modules'];
this.alias = config.alias;
+ this.modules = config.modules || DEFAULT_MODULES;
+ this.aliasFields = config.aliasFields || DEFAULT_ALIASFIELDS;
+ this.mainFields = config.mainFields || DEFAULT_MAINFIELDS;
- if (typeof this.modules === 'string') {
- this.modules = [this.modules];
- }
-
- let cwd = process.cwd();
+ ['modules', 'aliasFields', 'mainFields'].forEach(opt => {
+ typeof this[opt] === 'string' && (
+ this[opt] = [].concat(this[opt])
+ );
+ });
+
+ let pkgFile = util.getPkg();
+ let pkg = JSON.parse(pkgFile);
+ let cwd = util.currentDir;
+ let ext = cache.getExt();
+
+ // 优先级递减
+ this.aliasFields.forEach(fields => {
+ // 归类
+ util.isObject(pkg[fields]) && Object.keys(pkg[fields] || {}).forEach(key => {
+ // module形式的fieldsAlias归置于alias中,例: "xyz": "./src/xyz.js",alias优先级较大
+ if (key.indexOf('.') === -1) {
+ // => "xyz"、"xyz-xyz"
+ let value;
+ if (!pkg[fields][key]) {
+ value = 'false';
+ } else {
+ value = path.resolve(cwd, pkg[fields][key]);
+ }
+
+ // fields中key或value路径后缀与配置缺省值相同时,replace后缀
+ if (path.extname(value) === ext)
+ value = value.replace(ext, '');
+
+ this.alias = Object.assign({}, { [key]: value }, this.alias || {});
+ } else if (!path.isAbsolute(key)) {
+ // relative path
+ let value = path.resolve(cwd, pkg[fields][key]);
+ key = path.resolve(cwd, key);
+
+ // fields中key或value路径后缀与配置缺省值相同时,replace后缀
+ if (path.extname(key) === ext)
+ key = key.replace(ext, '');
+
+ if (path.extname(value) === ext)
+ value = value.replace(ext, '');
+
+ this.fieldsAlias = Object.assign({}, { [key]: value }, this.fieldsAlias || {});
+ }
+ });
+ });
this.modulePaths = this.modules.map(v => {
if (path.isAbsolute(v)) {
@@ -83,6 +131,14 @@ export default {
}
if (!pkg)
return null;
+
+ // make sure fields is used in this package.
+ pkg._activeFields = [];
+ this.aliasFields.forEach(field => {
+ if (pkg[field]) {
+ pkg._activeFields.push(field);
+ }
+ });
return {
pkg: pkg,
modulePath: o.modulePath,
@@ -95,10 +151,19 @@ export default {
if (!o) {
return null;
}
- let main = o.pkg.main || 'index.js';
- if (o.pkg.browser && typeof o.pkg.browser === 'string') {
- main = o.pkg.browser;
+
+ // 优先级递减
+ let mainField, main
+ for (let i = 0, l = this.mainFields.length; i < l; i++) {
+ mainField = this.mainFields[i];
+ if (o.pkg[mainField] && typeof o.pkg[mainField] === 'string') {
+ main = o.pkg[mainField];
+ break;
+ }
}
+
+ main = main || 'index.js';
+
return {
file: main,
modulePath: o.modulePath,
@@ -107,13 +172,72 @@ export default {
};
},
- resolveAlias (lib) {
+ /*
+ resolve package with contains different fields
+ */
+ resolveSelfFields (dir, pkg, lib) {
+ for (let i = 0, l = pkg._activeFields.length; i < l; i++) {
+ let field = pkg[pkg._activeFields[i]];
+ if (field) {
+ for (let k in field) {
+ // in Window, path may be dist\a\b, but in package.json it is ./dist/a/b, so can not just simply use ===
+ let matchPath = path.join(dir, k);
+ let requirePath = path.join(dir, lib);
+ if (matchPath === requirePath || matchPath === requirePath + path.extname(matchPath)) {
+ return field[k];
+ }
+ }
+ }
+ }
+ return null;
+ },
+
+ resolveFieldsAlias (lib) {
+ return lib && this.fieldsAlias && this.fieldsAlias[lib]
+ ? this.fieldsAlias[lib]
+ : lib;
+ },
+
+ replaceFieldsAlias (currentAlias, opath) {
+ let absolutePath;
+
+ if (path.isAbsolute(currentAlias)) {
+ absolutePath = currentAlias;
+
+ currentAlias = this.resolveFieldsAlias(absolutePath) !== absolutePath
+ ? this.resolveFieldsAlias(absolutePath)
+ : currentAlias;
+ } else if (currentAlias[0] === '.') {
+ absolutePath = path.join(opath.dir, currentAlias);
+
+ currentAlias = this.resolveFieldsAlias(absolutePath) !== absolutePath
+ ? this.resolveFieldsAlias(absolutePath)
+ : currentAlias;
+ } else if (
+ currentAlias.indexOf('/') === -1 || // require('asset');
+ currentAlias.indexOf('/') === currentAlias.length - 1 || // require('a/b/something/')
+ (currentAlias[0] === '@' && currentAlias.indexOf('/') !== -1 && currentAlias.lastIndexOf('/') === currentAlias.indexOf('/')) // require('@abc/something')
+ ) {
+ const mainFile = this.getMainFile(currentAlias);
+
+ if (mainFile) {
+ absolutePath = path.join(mainFile.dir, mainFile.file);
+ currentAlias = this.resolveFieldsAlias(absolutePath) !== absolutePath
+ ? this.resolveFieldsAlias(absolutePath)
+ : currentAlias;
+ }
+ }
+ return currentAlias;
+ },
+
+ resolveAlias (lib, opath) {
if (!this.alias)
return lib;
if (this._cacheAlias[lib]) {
return this._cacheAlias[lib];
}
let rst = lib;
+ let ext = cache.getExt();
for (let k in this.alias) {
let alias = this.alias[k];
@@ -128,13 +252,18 @@ export default {
}
} else {
if ((lib.indexOf(k) === 0 && lib === k) || (lib !== k && lib.indexOf(k + '/') === 0)) {
- this._cacheAlias[lib] = path.resolve(lib.replace(k, alias));
+ this._cacheAlias[lib] = lib.replace(k, alias);
+ if (this._cacheAlias[lib] !== 'false') {
+ this._cacheAlias[lib] = path.resolve(this._cacheAlias[lib]);
+ }
}
}
}
if (!this._cacheAlias[lib]) {
this._cacheAlias[lib] = lib;
}
+ // replace field alias
+ this._cacheAlias[lib] = this.replaceFieldsAlias(this._cacheAlias[lib], opath);
return this._cacheAlias[lib];
}
-}
\ No newline at end of file
+}
diff --git a/packages/wepy-cli/src/util.js b/packages/wepy-cli/src/util.js
index f89420827..e764c572c 100644
--- a/packages/wepy-cli/src/util.js
+++ b/packages/wepy-cli/src/util.js
@@ -478,6 +478,10 @@ const utils = {
let ignoreFile = path.join(this.currentDir, path.sep, '.wepyignore');
return this.isFile(ignoreFile) ? this.readFile(ignoreFile) : '';
},
+ getPkg () {
+ let pkgFile = path.join(this.currentDir, path.sep, 'package.json');
+ return this.isFile(pkgFile) ? this.readFile(pkgFile) : '{}';
+ },
getFiles (dir = process.cwd(), prefix = '') {
let cfiles = cache.getFileList(dir);
if (cfiles)
diff --git a/packages/wepy-cli/src/web/compile-script.js b/packages/wepy-cli/src/web/compile-script.js
index a4992cd69..4d7b6b07a 100644
--- a/packages/wepy-cli/src/web/compile-script.js
+++ b/packages/wepy-cli/src/web/compile-script.js
@@ -40,6 +40,7 @@ export default {
let wpyExt = params.wpyExt;
let depences = [];
+
// wpy.script.code = wpy.script.code.replace(/require\(['"]([\w\d_\-\.\/]+)['"]\)/ig, (match, lib) => {
wpy.script.code = wpy.script.code.replace(/require\(['"]([\w\d_\-\.\/@]+)['"]\)/ig, (match, lib) => {
if (lib === 'wepy')
@@ -51,14 +52,35 @@ export default {
let dep = {}, npmInfo;
- lib = resolve.resolveAlias(lib);
+ lib = resolve.resolveAlias(lib, opath);
- if (path.isAbsolute(lib)) {
+ if (lib === 'false') {
+ return '{}';
+ } else if (path.isAbsolute(lib)) {
source = lib;
} else if (lib[0] === '.') { // require('./something'');
- source = path.join(opath.dir, lib); // e:/src/util
+ let resolvedLib;
+ if (wpy.npm && wpy.npm.pkg._activeFields.length) {
+ resolvedLib = resolve.resolveSelfFields(wpy.npm.dir, wpy.npm.pkg, path.join(path.relative(wpy.npm.dir, opath.dir), lib));
+ }
+ if (resolvedLib) {
+ source = path.join(wpy.npm.dir, resolvedLib);
+ lib = path.relative(opath.dir, source);
+ if (lib[0] !== '.') {
+ lib = './' + lib;
+ }
+ } else {
+ source = path.join(opath.dir, lib);
+ }
+ npmInfo = wpy.npm; // relative path in npm package
} else if (lib.indexOf('/') === -1 || lib.indexOf('/') === lib.length - 1) { // require('asset');
+ // require('stream') -> browsers: emitter->emitter-component;
+ if (wpy.npm && wpy.npm.pkg._activeFields.length) {
+ let resolvedLib = resolve.resolveSelfFields(wpy.npm.dir, wpy.npm.pkg, lib);
+ lib = resolvedLib ? resolvedLib : lib;
+ }
+
let o = resolve.getMainFile(lib);
if (!o) {
let relative = path.relative(util.currentDir, wpy.script.src);
@@ -66,16 +88,24 @@ export default {
}
let pkg = o.pkg;
let main = pkg.main || 'index.js';
+
+ let resolvedFile;
+ if (o.pkg && o.pkg._activeFields.length) {
+ resolvedFile = resolve.resolveSelfFields(o.dir, o.pkg, o.file);
+ }
+ resolvedFile = resolvedFile ? resolvedFile : o.file;
+
+
if (lib === 'axios') {
- main = path.join('dist', 'axios.js');
+ resolvedFile = path.join('dist', 'axios.js');
} else if (lib === 'vue') {
- main = path.join('dist', 'vue.js');
+ resolvedFile = path.join('dist', 'vue.js');
}
if (pkg.browser && typeof pkg.browser === 'string') {
- main = pkg.browser;
+ resolvedFile = pkg.browser;
}
- source = path.join(o.dir, main);
- lib += path.sep + main;
+ source = path.join(o.dir, resolvedFile);
+ lib += path.sep + resolvedFile;
npmInfo = o;
} else { // require('babel-runtime/regenerator')
//console.log('3: ' + lib);
@@ -95,6 +125,8 @@ export default {
source += wpyExt;
} else if (util.isFile(source + '.js')) {
source += '.js';
+ } else if (util.isDir(source) && util.isFile(source + path.sep + 'index.js')) {
+ source += path.sep + 'index.js';
} else {
source = null;
}
diff --git a/packages/wepy-cli/templates/template/package.json b/packages/wepy-cli/templates/template/package.json
index db59540a7..af4d83220 100644
--- a/packages/wepy-cli/templates/template/package.json
+++ b/packages/wepy-cli/templates/template/package.json
@@ -8,6 +8,10 @@
"build": "cross-env NODE_ENV=production wepy build --no-cache",
"test": "echo \"Error: no test specified\" && exit 1"
},
+ "wepy": {
+ "module-a": false,
+ "./src/components/list": "./src/components/wepy-list.wpy"
+ },
"author": "",
"license": "MIT"
}
diff --git a/packages/wepy-cli/templates/template/src/components/wepy-list.wpy b/packages/wepy-cli/templates/template/src/components/wepy-list.wpy
new file mode 100644
index 000000000..07ac10620
--- /dev/null
+++ b/packages/wepy-cli/templates/template/src/components/wepy-list.wpy
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+ {{item.id}}: {{item.title}}
+
+
+
+
+
diff --git a/packages/wepy-cli/templates/template/src/pages/index-redux.wpy b/packages/wepy-cli/templates/template/src/pages/index-redux.wpy
index b76ad3a41..8f06f82e1 100644
--- a/packages/wepy-cli/templates/template/src/pages/index-redux.wpy
+++ b/packages/wepy-cli/templates/template/src/pages/index-redux.wpy
@@ -84,12 +84,16 @@
import wepy from 'wepy'
import { connect } from 'wepy-redux'
import List from '../components/list'
- import Panel from '../components/panel'
+ import Panel from '@/components/panel' // alias example
import Counter from 'counter' // alias example
+ import List from '../components/list' // aliasFields example
+ import moduleA from 'module-a' // aliasFields ignore module example
import Group from '../components/group'
import Toast from 'wepy-com-toast'
import testMixin from '../mixins/test'
+ console.log('moduleA ignored: ', moduleA) // => moduleA ignored: {}
+
@connect({
num (state) {
return state.counter.num
diff --git a/packages/wepy-cli/templates/template/src/pages/index.wpy b/packages/wepy-cli/templates/template/src/pages/index.wpy
index df70212ac..07e416084 100644
--- a/packages/wepy-cli/templates/template/src/pages/index.wpy
+++ b/packages/wepy-cli/templates/template/src/pages/index.wpy
@@ -79,13 +79,16 @@