diff --git a/package.json b/package.json
index 64d2288..5d61dbc 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"start": "jest test --watch",
"test": "jest test",
"test:webpack": "cd test && webpack",
- "test:webpack:ts": "cd test && TEST_EXT=ts webpack",
+ "test:webpack:ts": "cd test && cross-env TEST_EXT=ts webpack",
"prebuild": "rimraf ./lib && mkdirp ./lib",
"build:watch": "babel src -o lib/index.js -w",
"build": "babel src -o lib/index.js",
@@ -40,6 +40,7 @@
"babel-plugin-transform-es2015-spread": "^6.22.0",
"babel-preset-es2015": "^6.24.0",
"babel-preset-stage-0": "^6.22.0",
+ "cross-env": "^5.2.0",
"eslint": "^4.2.0",
"eslint-config-standard": "^10.2.1",
"eslint-loader": "^1.9.0",
diff --git a/src/index.js b/src/index.js
index 5125886..d271d35 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,445 +1,501 @@
-import { remove, readJson, existsSync, stat, readFile } from 'fs-extra';
-import { resolve, dirname, relative, join, parse } from 'path';
-import { optimize, LoaderTargetPlugin, JsonpTemplatePlugin } from 'webpack';
-import { ConcatSource } from 'webpack-sources';
-import globby from 'globby';
-import { defaults, values, uniq } from 'lodash';
-import MultiEntryPlugin from 'webpack/lib/MultiEntryPlugin';
-import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin';
-import FunctionModulePlugin from 'webpack/lib/FunctionModulePlugin';
-import NodeSourcePlugin from 'webpack/lib/node/NodeSourcePlugin';
-
-const { CommonsChunkPlugin } = optimize;
-
-const deprecated = function deprecated(obj, key, adapter, explain) {
- if (deprecated.warned.has(key)) {
- return;
- }
- const val = obj[key];
- if (typeof val === 'undefined') {
- return;
- }
- deprecated.warned.add(key);
- adapter(val);
- console.warn('[WXAppPlugin]', explain);
-};
-deprecated.warned = new Set();
-
-const stripExt = path => {
- const { dir, name } = parse(path);
- return join(dir, name);
-};
-
-const miniProgramTarget = compiler => {
- const { options } = compiler;
- compiler.apply(
- new JsonpTemplatePlugin(options.output),
- new FunctionModulePlugin(options.output),
- new NodeSourcePlugin(options.node),
- new LoaderTargetPlugin('web')
- );
-};
-
-export const Targets = {
- Wechat(compiler) {
- return miniProgramTarget(compiler);
- },
- Alipay(compiler) {
- return miniProgramTarget(compiler);
- }
-};
-
-export default class WXAppPlugin {
- constructor(options = {}) {
- this.options = defaults(options || {}, {
- clear: true,
- include: [],
- exclude: [],
- dot: false, // Include `.dot` files
- extensions: ['.js'],
- commonModuleName: 'common.js',
- enforceTarget: true,
- assetsChunkName: '__assets_chunk_name__'
- // base: undefined,
- });
-
- deprecated(
- this.options,
- 'scriptExt',
- val => this.options.extensions.unshift(val),
- 'Option `scriptExt` is deprecated. Please use `extensions` instead'
- );
-
- deprecated(
- this.options,
- 'forceTarge',
- val => (this.options.enforceTarget = val),
- 'Option `forceTarge` is deprecated. Please use `enforceTarget` instead'
- );
-
- this.options.extensions = uniq([...this.options.extensions, '.js']);
- this.options.include = [].concat(this.options.include);
- this.options.exclude = [].concat(this.options.exclude);
- }
-
- apply(compiler) {
- const { clear } = this.options;
- let isFirst = true;
-
- this.enforceTarget(compiler);
-
- compiler.plugin(
- 'run',
- this.try(async compiler => {
- await this.run(compiler);
- })
- );
-
- compiler.plugin(
- 'watch-run',
- this.try(async compiler => {
- await this.run(compiler.compiler);
- })
- );
-
- compiler.plugin(
- 'emit',
- this.try(async compilation => {
- if (clear && isFirst) {
- isFirst = false;
- await this.clear(compilation);
- }
-
- await this.toEmitTabBarIcons(compilation);
- })
- );
-
- compiler.plugin(
- 'after-emit',
- this.try(async compilation => {
- await this.toAddTabBarIconsDependencies(compilation);
- })
- );
- }
-
- try = handler => async (arg, callback) => {
- try {
- await handler(arg);
- callback();
- } catch (err) {
- callback(err);
- }
- };
-
- enforceTarget(compiler) {
- const { enforceTarget } = this.options;
- const { options } = compiler;
-
- if (enforceTarget) {
- const { target } = options;
- if (target !== Targets.Wechat && target !== Targets.Alipay) {
- options.target = Targets.Wechat;
- }
- if (!options.node || options.node.global) {
- options.node = options.node || {};
- options.node.global = false;
- }
- }
- }
-
- getBase(compiler) {
- const { base, extensions } = this.options;
- if (base) {
- return resolve(base);
- }
-
- const { options: compilerOptions } = compiler;
- const { context, entry } = compilerOptions;
-
- const getEntryFromCompiler = () => {
- if (typeof entry === 'string') {
- return entry;
- }
-
- const extRegExpStr = extensions
- .map(ext => ext.replace(/\./, '\\.'))
- .map(ext => `(${ext})`)
- .join('|');
-
- const appJSRegExp = new RegExp(`\\bapp(${extRegExpStr})?$`);
- const findAppJS = arr => arr.find(path => appJSRegExp.test(path));
-
- if (Array.isArray(entry)) {
- return findAppJS(entry);
- }
- if (typeof entry === 'object') {
- for (const key in entry) {
- if (!entry.hasOwnProperty(key)) {
- continue;
- }
-
- const val = entry[key];
- if (typeof val === 'string') {
- return val;
- }
- if (Array.isArray(val)) {
- return findAppJS(val);
- }
- }
- }
- };
-
- const entryFromCompiler = getEntryFromCompiler();
-
- if (entryFromCompiler) {
- return dirname(entryFromCompiler);
- }
-
- return context;
- }
-
- async getTabBarIcons(tabBar) {
- const tabBarIcons = new Set();
- const tabBarList = tabBar.list || [];
- for (const tabBarItem of tabBarList) {
- if (tabBarItem.iconPath) {
- tabBarIcons.add(tabBarItem.iconPath);
- }
- if (tabBarItem.selectedIconPath) {
- tabBarIcons.add(tabBarItem.selectedIconPath);
- }
- }
-
- this.tabBarIcons = tabBarIcons;
- }
-
- async toEmitTabBarIcons(compilation) {
- const emitIcons = [];
- this.tabBarIcons.forEach(iconPath => {
- const iconSrc = resolve(this.base, iconPath);
- const toEmitIcon = async () => {
- const iconStat = await stat(iconSrc);
- const iconSource = await readFile(iconSrc);
- compilation.assets[iconPath] = {
- size: () => iconStat.size,
- source: () => iconSource
- };
- };
- emitIcons.push(toEmitIcon());
- });
- await Promise.all(emitIcons);
- }
-
- toAddTabBarIconsDependencies(compilation) {
- const { fileDependencies } = compilation;
- this.tabBarIcons.forEach(iconPath => {
- if (!~fileDependencies.indexOf(iconPath)) {
- fileDependencies.push(iconPath);
- }
- });
- }
-
- async getEntryResource() {
- const appJSONFile = resolve(this.base, 'app.json');
- const { pages = [], subPackages = [], tabBar = {} } = await readJson(
- appJSONFile
- );
-
- const components = new Set();
- for (const page of pages) {
- await this.getComponents(components, resolve(this.base, page));
- }
-
- for (const subPackage of subPackages) {
- const { root, pages = [] } = subPackage;
-
- await Promise.all(
- pages.map(async page =>
- this.getComponents(components, resolve(this.base, join(root, page)))
- )
- );
- }
-
- this.getTabBarIcons(tabBar);
-
- return [
- 'app',
- ...pages,
- ...[].concat(...subPackages.map(v => v.pages.map(w => join(v.root, w)))),
- ...components
- ];
- }
-
- async getComponents(components, instance) {
- const { usingComponents = {} } =
- (await readJson(`${instance}.json`).catch(
- err => err && err.code !== 'ENOENT' && console.error(err)
- )) || {};
- const componentBase = parse(instance).dir;
- for (const relativeComponent of values(usingComponents)) {
- if (relativeComponent.indexOf('plugin://') === 0) continue;
- const component = resolve(componentBase, relativeComponent);
- if (!components.has(component)) {
- components.add(relative(this.base, component));
- await this.getComponents(components, component);
- }
- }
- }
-
- getFullScriptPath(path) {
- const {
- base,
- options: { extensions }
- } = this;
- for (const ext of extensions) {
- const fullPath = resolve(base, path + ext);
- if (existsSync(fullPath)) {
- return fullPath;
- }
- }
- }
-
- async clear(compilation) {
- const { path } = compilation.options.output;
- await remove(path);
- }
-
- addEntries(compiler, entries, chunkName) {
- compiler.apply(new MultiEntryPlugin(this.base, entries, chunkName));
- }
-
- async compileAssets(compiler) {
- const {
- options: { include, exclude, dot, assetsChunkName, extensions },
- entryResources
- } = this;
-
- compiler.plugin('compilation', compilation => {
- compilation.plugin('before-chunk-assets', () => {
- const assetsChunkIndex = compilation.chunks.findIndex(
- ({ name }) => name === assetsChunkName
- );
- if (assetsChunkIndex > -1) {
- compilation.chunks.splice(assetsChunkIndex, 1);
- }
- });
- });
-
- const patterns = entryResources
- .map(resource => `${resource}.*`)
- .concat(include);
-
- const entries = await globby(patterns, {
- cwd: this.base,
- nodir: true,
- realpath: true,
- ignore: [...extensions.map(ext => `**/*${ext}`), ...exclude],
- dot
- });
-
- this.addEntries(compiler, entries, assetsChunkName);
- }
-
- getChunkResourceRegExp() {
- if (this._chunkResourceRegex) {
- return this._chunkResourceRegex;
- }
-
- const {
- options: { extensions }
- } = this;
- const exts = extensions
- .map(ext => ext.replace(/\./g, '\\.'))
- .map(ext => `(${ext}$)`)
- .join('|');
- return new RegExp(exts);
- }
-
- applyCommonsChunk(compiler) {
- const {
- options: { commonModuleName },
- entryResources
- } = this;
-
- const scripts = entryResources.map(::this.getFullScriptPath);
-
- compiler.apply(
- new CommonsChunkPlugin({
- name: stripExt(commonModuleName),
- minChunks: ({ resource }) => {
- if (resource) {
- const regExp = this.getChunkResourceRegExp();
- return regExp.test(resource) && scripts.indexOf(resource) < 0;
- }
- return false;
- }
- })
- );
- }
-
- addScriptEntry(compiler, entry, name) {
- compiler.plugin('make', (compilation, callback) => {
- const dep = SingleEntryPlugin.createDependency(entry, name);
- compilation.addEntry(this.base, dep, name, callback);
- });
- }
-
- compileScripts(compiler) {
- this.applyCommonsChunk(compiler);
- this.entryResources
- .filter(resource => resource !== 'app')
- .forEach(resource => {
- const fullPath = this.getFullScriptPath(resource);
- this.addScriptEntry(compiler, fullPath, resource);
- });
- }
-
- toModifyTemplate(compilation) {
- const { commonModuleName } = this.options;
- const { target } = compilation.options;
- const commonChunkName = stripExt(commonModuleName);
- const globalVar = target.name === 'Alipay' ? 'my' : 'wx';
-
- // inject chunk entries
- compilation.chunkTemplate.plugin('render', (core, { name }) => {
- if (this.entryResources.indexOf(name) >= 0) {
- const relativePath = relative(dirname(name), `./${commonModuleName}`);
- const posixPath = relativePath.replace(/\\/g, '/');
- const source = core.source();
-
- // eslint-disable-next-line max-len
- const injectContent = `; function webpackJsonp() { require("./${posixPath}"); ${globalVar}.webpackJsonp.apply(null, arguments); }`;
-
- if (source.indexOf(injectContent) < 0) {
- const concatSource = new ConcatSource(core);
- concatSource.add(injectContent);
- return concatSource;
- }
- }
- return core;
- });
-
- // replace `window` to `global` in common chunk
- compilation.mainTemplate.plugin('bootstrap', (source, chunk) => {
- const windowRegExp = new RegExp('window', 'g');
- if (chunk.name === commonChunkName) {
- return source.replace(windowRegExp, globalVar);
- }
- return source;
- });
-
- // override `require.ensure()`
- compilation.mainTemplate.plugin(
- 'require-ensure',
- () => 'throw new Error("Not chunk loading available");'
- );
- }
-
- async run(compiler) {
- this.base = this.getBase(compiler);
- this.entryResources = await this.getEntryResource();
- compiler.plugin('compilation', ::this.toModifyTemplate);
- this.compileScripts(compiler);
- await this.compileAssets(compiler);
- }
-}
+import { remove, readJson, existsSync, stat, readFile } from 'fs-extra';
+import { resolve, dirname, relative, join, parse } from 'path';
+import { optimize, LoaderTargetPlugin, JsonpTemplatePlugin } from 'webpack';
+import { ConcatSource } from 'webpack-sources';
+import globby from 'globby';
+import { defaults, values, uniq } from 'lodash';
+import MultiEntryPlugin from 'webpack/lib/MultiEntryPlugin';
+import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin';
+import FunctionModulePlugin from 'webpack/lib/FunctionModulePlugin';
+import NodeSourcePlugin from 'webpack/lib/node/NodeSourcePlugin';
+
+const { CommonsChunkPlugin } = optimize;
+
+const deprecated = function deprecated(obj, key, adapter, explain) {
+ if (deprecated.warned.has(key)) {
+ return;
+ }
+ const val = obj[key];
+ if (typeof val === 'undefined') {
+ return;
+ }
+ deprecated.warned.add(key);
+ adapter(val);
+ console.warn('[WXAppPlugin]', explain);
+};
+deprecated.warned = new Set();
+
+const stripExt = path => {
+ const { dir, name } = parse(path);
+ return join(dir, name);
+};
+
+const miniProgramTarget = compiler => {
+ const { options } = compiler;
+ compiler.apply(
+ new JsonpTemplatePlugin(options.output),
+ new FunctionModulePlugin(options.output),
+ new NodeSourcePlugin(options.node),
+ new LoaderTargetPlugin('web')
+ );
+};
+
+export const Targets = {
+ Wechat(compiler) {
+ return miniProgramTarget(compiler);
+ },
+ Alipay(compiler) {
+ return miniProgramTarget(compiler);
+ }
+};
+
+export default class WXAppPlugin {
+ constructor(options = {}) {
+ this.options = defaults(options || {}, {
+ clear: true,
+ include: [],
+ exclude: [],
+ dot: false, // Include `.dot` files
+ extensions: ['.js'],
+ commonModuleName: 'common.js',
+ enforceTarget: true,
+ assetsChunkName: '__assets_chunk_name__'
+ // base: undefined,
+ });
+
+ deprecated(
+ this.options,
+ 'scriptExt',
+ val => this.options.extensions.unshift(val),
+ 'Option `scriptExt` is deprecated. Please use `extensions` instead'
+ );
+
+ deprecated(
+ this.options,
+ 'forceTarge',
+ val => (this.options.enforceTarget = val),
+ 'Option `forceTarge` is deprecated. Please use `enforceTarget` instead'
+ );
+
+ this.options.extensions = uniq([...this.options.extensions, '.js']);
+ this.options.include = [].concat(this.options.include);
+ this.options.exclude = [].concat(this.options.exclude);
+ }
+
+ apply(compiler) {
+ const { clear } = this.options;
+ let isFirst = true;
+
+ this.enforceTarget(compiler);
+
+ compiler.plugin(
+ 'run',
+ this.try(async compiler => {
+ await this.run(compiler);
+ })
+ );
+
+ compiler.plugin(
+ 'watch-run',
+ this.try(async compiler => {
+ await this.run(compiler.compiler);
+ })
+ );
+
+ compiler.plugin(
+ 'emit',
+ this.try(async compilation => {
+ if (clear && isFirst) {
+ isFirst = false;
+ await this.clear(compilation);
+ }
+
+ await this.toEmitTabBarIcons(compilation);
+ })
+ );
+
+ compiler.plugin(
+ 'after-emit',
+ this.try(async compilation => {
+ await this.toAddTabBarIconsDependencies(compilation);
+ })
+ );
+ }
+
+ try = handler => async (arg, callback) => {
+ try {
+ await handler(arg);
+ callback();
+ } catch (err) {
+ callback(err);
+ }
+ };
+
+ enforceTarget(compiler) {
+ const { enforceTarget } = this.options;
+ const { options } = compiler;
+
+ if (enforceTarget) {
+ const { target } = options;
+ if (target !== Targets.Wechat && target !== Targets.Alipay) {
+ options.target = Targets.Wechat;
+ }
+ if (!options.node || options.node.global) {
+ options.node = options.node || {};
+ options.node.global = false;
+ }
+ }
+ }
+
+ getBase(compiler) {
+ const { base, extensions } = this.options;
+ if (base) {
+ return resolve(base);
+ }
+
+ const { options: compilerOptions } = compiler;
+ const { context, entry } = compilerOptions;
+
+ const getEntryFromCompiler = () => {
+ if (typeof entry === 'string') {
+ return entry;
+ }
+
+ const extRegExpStr = extensions
+ .map(ext => ext.replace(/\./, '\\.'))
+ .map(ext => `(${ext})`)
+ .join('|');
+
+ const appJSRegExp = new RegExp(`\\bapp(${extRegExpStr})?$`);
+ const findAppJS = arr => arr.find(path => appJSRegExp.test(path));
+
+ if (Array.isArray(entry)) {
+ return findAppJS(entry);
+ }
+ if (typeof entry === 'object') {
+ for (const key in entry) {
+ if (!entry.hasOwnProperty(key)) {
+ continue;
+ }
+
+ const val = entry[key];
+ if (typeof val === 'string') {
+ return val;
+ }
+ if (Array.isArray(val)) {
+ return findAppJS(val);
+ }
+ }
+ }
+ };
+
+ const entryFromCompiler = getEntryFromCompiler();
+
+ if (entryFromCompiler) {
+ return dirname(entryFromCompiler);
+ }
+
+ return context;
+ }
+
+ getTabBarIcons(tabBar) {
+ const tabBarIcons = new Set();
+ const tabBarList = tabBar.list || [];
+ for (const tabBarItem of tabBarList) {
+ if (tabBarItem.iconPath) {
+ tabBarIcons.add(tabBarItem.iconPath);
+ }
+ if (tabBarItem.selectedIconPath) {
+ tabBarIcons.add(tabBarItem.selectedIconPath);
+ }
+ }
+
+ return tabBarIcons
+ }
+
+ async toEmitTabBarIcons(compilation) {
+ const emitIcons = [];
+ this.tabBarIcons.forEach(iconPath => {
+ const iconSrc = resolve(this.base, iconPath);
+ const toEmitIcon = async () => {
+ const iconStat = await stat(iconSrc);
+ const iconSource = await readFile(iconSrc);
+ compilation.assets[iconPath] = {
+ size: () => iconStat.size,
+ source: () => iconSource
+ };
+ };
+ emitIcons.push(toEmitIcon());
+ });
+ await Promise.all(emitIcons);
+ }
+
+ toAddTabBarIconsDependencies(compilation) {
+ const { fileDependencies } = compilation;
+ this.tabBarIcons.forEach(iconPath => {
+ if (!~fileDependencies.indexOf(iconPath)) {
+ fileDependencies.push(iconPath);
+ }
+ });
+ }
+
+ async getEntryResources(pages, subPackages) {
+ let subEntryResources = [];
+ let entryResources = []
+
+ const components = new Set();
+ for (const page of pages) {
+ await this.getComponents(components, resolve(this.base, page));
+ }
+
+ for (const subPackage of subPackages) {
+ const { root, pages: subPages = [] } = subPackage;
+
+ for (const subPage of subPages) {
+ await this.getComponents(components, resolve(this.base, join(root, subPage)));
+ }
+
+ subEntryResources.push([...subPages.map(subPage => join(root, subPage))]);
+ }
+
+ entryResources = ['app', ...pages, ...components]
+
+ return {
+ entryResources,
+ subEntryResources
+ };
+ }
+
+ async getComponents(components, instance) {
+ const { usingComponents = {} } =
+ (await readJson(`${instance}.json`).catch(
+ err => err && err.code !== 'ENOENT' && console.error(err)
+ )) || {};
+ const componentBase = parse(instance).dir;
+ for (const relativeComponent of values(usingComponents)) {
+ if (relativeComponent.indexOf('plugin://') === 0) {
+ continue;
+ }
+ const component = resolve(componentBase, relativeComponent);
+ if (!components.has(component)) {
+ components.add(relative(this.base, component));
+ await this.getComponents(components, component);
+ }
+ }
+ }
+
+ getFullScriptPath(path) {
+ const {
+ base,
+ options: { extensions }
+ } = this;
+
+ for (const ext of extensions) {
+ const fullPath = resolve(base, path + ext);
+ if (existsSync(fullPath)) {
+ return fullPath;
+ }
+ }
+ }
+
+ async clear(compilation) {
+ const { path } = compilation.options.output;
+ await remove(path);
+ }
+
+ addEntries(compiler, entries, chunkName) {
+ compiler.apply(new MultiEntryPlugin(this.base, entries, chunkName));
+ }
+
+ async compileAssets(compiler) {
+ const {
+ options: { include, exclude, dot, assetsChunkName, extensions },
+ entryResources,
+ subEntryResources
+ } = this;
+
+ compiler.plugin('compilation', compilation => {
+ compilation.plugin('before-chunk-assets', () => {
+ const assetsChunkIndex = compilation.chunks.findIndex(
+ ({ name }) => name === assetsChunkName
+ );
+ if (assetsChunkIndex > -1) {
+ compilation.chunks.splice(assetsChunkIndex, 1);
+ }
+ });
+ });
+
+ const patterns = entryResources
+ .concat(...subEntryResources)
+ .map(resource => `${resource}.*`)
+ .concat(include);
+
+ const entries = await globby(patterns, {
+ cwd: this.base,
+ nodir: true,
+ realpath: true,
+ ignore: [...extensions.map(ext => `**/*${ext}`), ...exclude],
+ dot
+ });
+
+ this.addEntries(compiler, entries, assetsChunkName);
+ }
+
+ getChunkResourceRegExp() {
+ if (this._chunkResourceRegex) {
+ return this._chunkResourceRegex;
+ }
+
+ const {
+ options: { extensions }
+ } = this;
+ const exts = extensions
+ .map(ext => ext.replace(/\./g, '\\.'))
+ .map(ext => `(${ext}$)`)
+ .join('|');
+ return new RegExp(exts);
+ }
+
+ applyCommonsChunk(compiler) {
+ const {
+ options: { commonModuleName },
+ entryResources,
+ subEntryResources
+ } = this;
+
+ const flatSubEntryResources = [].concat(...subEntryResources.map(v => v));
+ const scripts = entryResources.concat(flatSubEntryResources).map(::this.getFullScriptPath);
+
+ const isWin = scripts.findIndex(v => v.indexOf('\\') >= 0) !== -1;
+ const lastSubDirs = new Set();
+ subEntryResources.forEach((pages, index) => {
+ if (pages.length) {
+ const subDir = isWin
+ ? pages[0].slice(0, pages[0].lastIndexOf('\\') + 1)
+ : pages[0].slice(0, pages[0].lastIndexOf('/') + 1);
+
+ compiler.apply(
+ new CommonsChunkPlugin({
+ name: stripExt(`${subDir}${commonModuleName}`),
+ filename: `${subDir}${commonModuleName}`,
+ minChunks: ({ resource }) => {
+ lastSubDirs.add(subDir);
+
+ if (index === 0) {
+ const regExp = this.getChunkResourceRegExp();
+ return resource && regExp.test(resource) && scripts.indexOf(resource) < 0;
+ } else {
+ return resource.indexOf(Array.from(lastSubDirs)[index - 1]) < 0;
+ }
+ },
+ })
+ );
+ }
+ });
+
+ compiler.apply(
+ new CommonsChunkPlugin({
+ name: stripExt(commonModuleName),
+ minChunks: ({ resource }) => {
+ return resource && resource.indexOf(Array.from(lastSubDirs).pop()) < 0;
+ }
+ })
+ );
+ }
+
+ addScriptEntry(compiler, entry, name) {
+ compiler.plugin('make', (compilation, callback) => {
+ const dep = SingleEntryPlugin.createDependency(entry, name);
+ compilation.addEntry(this.base, dep, name, callback);
+ });
+ }
+
+ compileScripts(compiler) {
+ this.applyCommonsChunk(compiler);
+ this.entryResources
+ .filter(resource => resource !== 'app')
+ .forEach(resource => {
+ const fullPath = this.getFullScriptPath(resource);
+ this.addScriptEntry(compiler, fullPath, resource);
+ });
+
+ this.subEntryResources.forEach(item => {
+ item.forEach(resource => {
+ const fullPath = this.getFullScriptPath(resource);
+ this.addScriptEntry(compiler, fullPath, resource);
+ });
+ });
+ }
+
+ toModifyTemplate(compilation) {
+ const { commonModuleName } = this.options;
+ const { target } = compilation.options;
+ const commonChunkName = stripExt(commonModuleName);
+ const globalVar = target.name === 'Alipay' ? 'my' : 'wx';
+ const subEntryResources = [].concat(...this.subEntryResources.map(v => v))
+ const scripts = [].concat(this.entryResources).concat(subEntryResources);
+ const isWin = scripts.findIndex(v => v.indexOf('\\') >= 0) !== -1;
+ const subDirs = this.subEntryResources
+ .filter(v => v.length)
+ .map(v => isWin
+ ? v[0].slice(0, v[0].lastIndexOf('\\') + 1)
+ : v[0].slice(0, v[0].lastIndexOf('/') + 1));
+
+ // inject chunk entries
+ compilation.chunkTemplate.plugin('render', (core, { name }) => {
+ if (scripts.indexOf(name) >= 0 || subDirs.find(v => name.indexOf(v) >= 0)) {
+ let relativePath;
+ if (subEntryResources.indexOf(name) >= 0) {
+ relativePath = `${commonModuleName}`
+ } else {
+ relativePath = relative(dirname(name), `./${commonModuleName}`);
+ }
+
+ const posixPath = relativePath.replace(/\\/g, '/');
+ const source = core.source();
+
+ // eslint-disable-next-line max-len
+ const injectContent = `; function webpackJsonp() { require("./${posixPath}"); ${globalVar}.webpackJsonp.apply(null, arguments); }`;
+
+ if (source.indexOf(injectContent) < 0) {
+ const concatSource = new ConcatSource(core);
+ concatSource.add(injectContent);
+ return concatSource;
+ }
+ }
+ return core;
+ });
+
+ // replace `window` to `global` in common chunk
+ compilation.mainTemplate.plugin('bootstrap', (source, chunk) => {
+ const windowRegExp = new RegExp('window', 'g');
+ if (chunk.name === commonChunkName) {
+ return source.replace(windowRegExp, globalVar);
+ }
+ return source;
+ });
+
+ // override `require.ensure()`
+ compilation.mainTemplate.plugin(
+ 'require-ensure',
+ () => 'throw new Error("Not chunk loading available");'
+ );
+ }
+
+ async run(compiler) {
+ this.base = this.getBase(compiler);
+
+ const appJSONFile = resolve(this.base, 'app.json');
+ const { pages = [], subPackages = [], tabBar = {} } = await readJson(appJSONFile);
+
+ this.tabBarIcons = this.getTabBarIcons(tabBar);
+
+ const { entryResources, subEntryResources } = await this.getEntryResources(pages, subPackages);
+ this.entryResources = entryResources;
+ this.subEntryResources = subEntryResources;
+
+ compiler.plugin('compilation', ::this.toModifyTemplate);
+ this.compileScripts(compiler);
+ await this.compileAssets(compiler);
+ }
+}
diff --git a/test/src/js/app.json b/test/src/js/app.json
index 12ffc49..322e569 100644
--- a/test/src/js/app.json
+++ b/test/src/js/app.json
@@ -23,6 +23,13 @@
"productDetail",
"productList"
]
+ },
+ {
+ "root": "pages/product2",
+ "pages": [
+ "productDetail",
+ "productList"
+ ]
}
],
"window":{
diff --git a/test/src/js/pages/index/index.js b/test/src/js/pages/index/index.js
index 0b52d56..1f501e5 100644
--- a/test/src/js/pages/index/index.js
+++ b/test/src/js/pages/index/index.js
@@ -9,21 +9,19 @@ const app = getApp(); // eslint-disable-line no-undef
Page({
data: {
motto: 'Hello World',
- userInfo: {},
},
- //事件处理函数
- bindViewTap() {
+ goToSubList1() {
wx.navigateTo({
- url: '../logs/logs',
+ url: '../product/productList',
});
},
- goToSubList() {
+ goToSubList2() {
wx.navigateTo({
- url: '../product/productList',
+ url: '../product2/productList',
});
},
onLoad() {
-
+ console.log(1)
// await delay();
// const log = flow(() => {
@@ -31,11 +29,5 @@ Page({
// });
// log();
-
- //调用应用实例的方法获取全局数据
- app.getUserInfo((userInfo) => {
- //更新数据
- this.setData({ userInfo });
- });
},
});
diff --git a/test/src/js/pages/index/index.wxml b/test/src/js/pages/index/index.wxml
index 6fa58f8..7af10b9 100644
--- a/test/src/js/pages/index/index.wxml
+++ b/test/src/js/pages/index/index.wxml
@@ -1,11 +1,10 @@
-
-
- {{userInfo.nickName}}
-
+
+
{{motto}}
- go to subPackages
+ go to subPackages1
+ go to subPackages2
diff --git a/test/src/js/pages/product/product.service.js b/test/src/js/pages/product/product.service.js
new file mode 100644
index 0000000..e37d21f
--- /dev/null
+++ b/test/src/js/pages/product/product.service.js
@@ -0,0 +1,9 @@
+export default class Product {
+ constructor() {
+ this.name = 'CAR'
+ }
+
+ getProductName() {
+ return this.name
+ }
+}
\ No newline at end of file
diff --git a/test/src/js/pages/product/productDetail.js b/test/src/js/pages/product/productDetail.js
index b349c0b..a8b3093 100644
--- a/test/src/js/pages/product/productDetail.js
+++ b/test/src/js/pages/product/productDetail.js
@@ -1,5 +1,7 @@
import { formatTime } from '../../utils/util';
+import Product from './product.service';
+const productService = new Product();
Page({
data: {
@@ -10,6 +12,7 @@ Page({
logs: (wx.getStorageSync('logs') || []).map(function (log) {
return formatTime(new Date(log));
}),
+ productName: productService.getProductName()
});
}
});
diff --git a/test/src/js/pages/product/productDetail.json b/test/src/js/pages/product/productDetail.json
index 69bae8d..7bf6b30 100644
--- a/test/src/js/pages/product/productDetail.json
+++ b/test/src/js/pages/product/productDetail.json
@@ -1,5 +1,5 @@
{
- "navigationBarTitleText": "分包明细",
+ "navigationBarTitleText": "分包明细1",
"usingComponents": {
"log-component": "../../components/log-component/log-component"
}
diff --git a/test/src/js/pages/product/productDetail.wxml b/test/src/js/pages/product/productDetail.wxml
index 0e2e86f..137fbe3 100644
--- a/test/src/js/pages/product/productDetail.wxml
+++ b/test/src/js/pages/product/productDetail.wxml
@@ -1,6 +1,6 @@
- {{index + 1}}. {{log}}
+ {{index + 1}}. {{log}} {{productName}}
diff --git a/test/src/js/pages/product/productList.js b/test/src/js/pages/product/productList.js
index f927edb..3b33532 100644
--- a/test/src/js/pages/product/productList.js
+++ b/test/src/js/pages/product/productList.js
@@ -2,7 +2,8 @@
// import { flow } from 'lodash';
// const delay = (t = 0) => new Promise((resolve) => setTimeout(resolve, t));
-
+import Product from './product.service';
+const productService = new Product();
//获取应用实例
const app = getApp(); // eslint-disable-line no-undef
@@ -26,11 +27,8 @@ Page({
// });
// log();
-
- //调用应用实例的方法获取全局数据
- app.getUserInfo((userInfo) => {
- //更新数据
- this.setData({ userInfo });
- });
+ this.setData({
+ productName: productService.getProductName()
+ })
},
});
diff --git a/test/src/js/pages/product/productList.json b/test/src/js/pages/product/productList.json
index 19af1ed..a8f0ff9 100644
--- a/test/src/js/pages/product/productList.json
+++ b/test/src/js/pages/product/productList.json
@@ -1,6 +1,7 @@
{
- "usingComponents": {
- "index-component": "../../components/index-component/index-component"
- }
+ "navigationBarTitleText": "分包列表1",
+ "usingComponents": {
+ "index-component": "../../components/index-component/index-component"
}
+}
\ No newline at end of file
diff --git a/test/src/js/pages/product/productList.wxml b/test/src/js/pages/product/productList.wxml
index 7c35a94..5ae5509 100644
--- a/test/src/js/pages/product/productList.wxml
+++ b/test/src/js/pages/product/productList.wxml
@@ -1,35 +1,11 @@
-
- click me and go to detail page
-
- {{userInfo.nickName}}
-
-
- {{motto}}
-
-
-
-
-
-
- click me and go to detail page
-
- {{userInfo.nickName}}
-
- {{motto}}
+ {{motto}} productName is {{productName}}
-
-
-
-
-
+
click me and go to detail page
-
- {{userInfo.nickName}}
-
-
- {{motto}}
+
+
diff --git a/test/src/js/pages/product2/product.service.js b/test/src/js/pages/product2/product.service.js
new file mode 100644
index 0000000..e37d21f
--- /dev/null
+++ b/test/src/js/pages/product2/product.service.js
@@ -0,0 +1,9 @@
+export default class Product {
+ constructor() {
+ this.name = 'CAR'
+ }
+
+ getProductName() {
+ return this.name
+ }
+}
\ No newline at end of file
diff --git a/test/src/js/pages/product2/productDetail.js b/test/src/js/pages/product2/productDetail.js
new file mode 100644
index 0000000..a8b3093
--- /dev/null
+++ b/test/src/js/pages/product2/productDetail.js
@@ -0,0 +1,18 @@
+
+import { formatTime } from '../../utils/util';
+import Product from './product.service';
+const productService = new Product();
+
+Page({
+ data: {
+ logs: [],
+ },
+ onLoad() {
+ this.setData({
+ logs: (wx.getStorageSync('logs') || []).map(function (log) {
+ return formatTime(new Date(log));
+ }),
+ productName: productService.getProductName()
+ });
+ }
+});
diff --git a/test/src/js/pages/product2/productDetail.json b/test/src/js/pages/product2/productDetail.json
new file mode 100644
index 0000000..d6959de
--- /dev/null
+++ b/test/src/js/pages/product2/productDetail.json
@@ -0,0 +1,7 @@
+{
+ "navigationBarTitleText": "分包明细2",
+ "usingComponents": {
+ "log-component": "../../components/log-component/log-component"
+ }
+ }
+
\ No newline at end of file
diff --git a/test/src/js/pages/product2/productDetail.wxml b/test/src/js/pages/product2/productDetail.wxml
new file mode 100644
index 0000000..137fbe3
--- /dev/null
+++ b/test/src/js/pages/product2/productDetail.wxml
@@ -0,0 +1,6 @@
+
+
+
+ {{index + 1}}. {{log}} {{productName}}
+
+
diff --git a/test/src/js/pages/product2/productDetail.wxss b/test/src/js/pages/product2/productDetail.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/test/src/js/pages/product2/productList.js b/test/src/js/pages/product2/productList.js
new file mode 100644
index 0000000..3b33532
--- /dev/null
+++ b/test/src/js/pages/product2/productList.js
@@ -0,0 +1,34 @@
+
+// import { flow } from 'lodash';
+
+// const delay = (t = 0) => new Promise((resolve) => setTimeout(resolve, t));
+import Product from './product.service';
+const productService = new Product();
+//获取应用实例
+const app = getApp(); // eslint-disable-line no-undef
+
+Page({
+ data: {
+ motto: 'Hello List',
+ userInfo: {},
+ },
+ //事件处理函数
+ bindViewTap() {
+ wx.navigateTo({
+ url: './productDetail',
+ });
+ },
+ onLoad() {
+
+ // await delay();
+
+ // const log = flow(() => {
+ // console.log('onLoad');
+ // });
+
+ // log();
+ this.setData({
+ productName: productService.getProductName()
+ })
+ },
+});
diff --git a/test/src/js/pages/product2/productList.json b/test/src/js/pages/product2/productList.json
new file mode 100644
index 0000000..828eb8d
--- /dev/null
+++ b/test/src/js/pages/product2/productList.json
@@ -0,0 +1,6 @@
+{
+ "navigationBarTitleText": "分包列表2",
+ "usingComponents": {
+ "index-component": "../../components/index-component/index-component"
+ }
+}
\ No newline at end of file
diff --git a/test/src/js/pages/product2/productList.wxml b/test/src/js/pages/product2/productList.wxml
new file mode 100644
index 0000000..c2348bf
--- /dev/null
+++ b/test/src/js/pages/product2/productList.wxml
@@ -0,0 +1,11 @@
+
+
+
+ {{motto}}
+
+
+ click me and go to detail page
+
+
+
+
diff --git a/test/src/js/pages/product2/productList.wxss b/test/src/js/pages/product2/productList.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/test/src/ts/app.json b/test/src/ts/app.json
index 12ffc49..322e569 100644
--- a/test/src/ts/app.json
+++ b/test/src/ts/app.json
@@ -23,6 +23,13 @@
"productDetail",
"productList"
]
+ },
+ {
+ "root": "pages/product2",
+ "pages": [
+ "productDetail",
+ "productList"
+ ]
}
],
"window":{
diff --git a/test/src/ts/pages/index/index.ts b/test/src/ts/pages/index/index.ts
index 0b52d56..023155e 100644
--- a/test/src/ts/pages/index/index.ts
+++ b/test/src/ts/pages/index/index.ts
@@ -9,17 +9,15 @@ const app = getApp(); // eslint-disable-line no-undef
Page({
data: {
motto: 'Hello World',
- userInfo: {},
},
- //事件处理函数
- bindViewTap() {
+ goToSubList1() {
wx.navigateTo({
- url: '../logs/logs',
+ url: '../product/productList',
});
},
- goToSubList() {
+ goToSubList2() {
wx.navigateTo({
- url: '../product/productList',
+ url: '../product2/productList',
});
},
onLoad() {
@@ -31,11 +29,5 @@ Page({
// });
// log();
-
- //调用应用实例的方法获取全局数据
- app.getUserInfo((userInfo) => {
- //更新数据
- this.setData({ userInfo });
- });
},
});
diff --git a/test/src/ts/pages/index/index.wxml b/test/src/ts/pages/index/index.wxml
index 6fa58f8..7af10b9 100644
--- a/test/src/ts/pages/index/index.wxml
+++ b/test/src/ts/pages/index/index.wxml
@@ -1,11 +1,10 @@
-
-
- {{userInfo.nickName}}
-
+
+
{{motto}}
- go to subPackages
+ go to subPackages1
+ go to subPackages2
diff --git a/test/src/ts/pages/product/product.service.ts b/test/src/ts/pages/product/product.service.ts
new file mode 100644
index 0000000..e37d21f
--- /dev/null
+++ b/test/src/ts/pages/product/product.service.ts
@@ -0,0 +1,9 @@
+export default class Product {
+ constructor() {
+ this.name = 'CAR'
+ }
+
+ getProductName() {
+ return this.name
+ }
+}
\ No newline at end of file
diff --git a/test/src/ts/pages/product/productDetail.json b/test/src/ts/pages/product/productDetail.json
index 69bae8d..7bf6b30 100644
--- a/test/src/ts/pages/product/productDetail.json
+++ b/test/src/ts/pages/product/productDetail.json
@@ -1,5 +1,5 @@
{
- "navigationBarTitleText": "分包明细",
+ "navigationBarTitleText": "分包明细1",
"usingComponents": {
"log-component": "../../components/log-component/log-component"
}
diff --git a/test/src/ts/pages/product/productDetail.ts b/test/src/ts/pages/product/productDetail.ts
index b349c0b..a8b3093 100644
--- a/test/src/ts/pages/product/productDetail.ts
+++ b/test/src/ts/pages/product/productDetail.ts
@@ -1,5 +1,7 @@
import { formatTime } from '../../utils/util';
+import Product from './product.service';
+const productService = new Product();
Page({
data: {
@@ -10,6 +12,7 @@ Page({
logs: (wx.getStorageSync('logs') || []).map(function (log) {
return formatTime(new Date(log));
}),
+ productName: productService.getProductName()
});
}
});
diff --git a/test/src/ts/pages/product/productDetail.wxml b/test/src/ts/pages/product/productDetail.wxml
index 0e2e86f..137fbe3 100644
--- a/test/src/ts/pages/product/productDetail.wxml
+++ b/test/src/ts/pages/product/productDetail.wxml
@@ -1,6 +1,6 @@
- {{index + 1}}. {{log}}
+ {{index + 1}}. {{log}} {{productName}}
diff --git a/test/src/ts/pages/product/productList.json b/test/src/ts/pages/product/productList.json
index 19af1ed..a8f0ff9 100644
--- a/test/src/ts/pages/product/productList.json
+++ b/test/src/ts/pages/product/productList.json
@@ -1,6 +1,7 @@
{
- "usingComponents": {
- "index-component": "../../components/index-component/index-component"
- }
+ "navigationBarTitleText": "分包列表1",
+ "usingComponents": {
+ "index-component": "../../components/index-component/index-component"
}
+}
\ No newline at end of file
diff --git a/test/src/ts/pages/product/productList.ts b/test/src/ts/pages/product/productList.ts
index f927edb..3b33532 100644
--- a/test/src/ts/pages/product/productList.ts
+++ b/test/src/ts/pages/product/productList.ts
@@ -2,7 +2,8 @@
// import { flow } from 'lodash';
// const delay = (t = 0) => new Promise((resolve) => setTimeout(resolve, t));
-
+import Product from './product.service';
+const productService = new Product();
//获取应用实例
const app = getApp(); // eslint-disable-line no-undef
@@ -26,11 +27,8 @@ Page({
// });
// log();
-
- //调用应用实例的方法获取全局数据
- app.getUserInfo((userInfo) => {
- //更新数据
- this.setData({ userInfo });
- });
+ this.setData({
+ productName: productService.getProductName()
+ })
},
});
diff --git a/test/src/ts/pages/product/productList.wxml b/test/src/ts/pages/product/productList.wxml
index 7c35a94..5ae5509 100644
--- a/test/src/ts/pages/product/productList.wxml
+++ b/test/src/ts/pages/product/productList.wxml
@@ -1,35 +1,11 @@
-
- click me and go to detail page
-
- {{userInfo.nickName}}
-
-
- {{motto}}
-
-
-
-
-
-
- click me and go to detail page
-
- {{userInfo.nickName}}
-
- {{motto}}
+ {{motto}} productName is {{productName}}
-
-
-
-
-
+
click me and go to detail page
-
- {{userInfo.nickName}}
-
-
- {{motto}}
+
+
diff --git a/test/src/ts/pages/product2/product.service.ts b/test/src/ts/pages/product2/product.service.ts
new file mode 100644
index 0000000..e37d21f
--- /dev/null
+++ b/test/src/ts/pages/product2/product.service.ts
@@ -0,0 +1,9 @@
+export default class Product {
+ constructor() {
+ this.name = 'CAR'
+ }
+
+ getProductName() {
+ return this.name
+ }
+}
\ No newline at end of file
diff --git a/test/src/ts/pages/product2/productDetail.json b/test/src/ts/pages/product2/productDetail.json
new file mode 100644
index 0000000..d6959de
--- /dev/null
+++ b/test/src/ts/pages/product2/productDetail.json
@@ -0,0 +1,7 @@
+{
+ "navigationBarTitleText": "分包明细2",
+ "usingComponents": {
+ "log-component": "../../components/log-component/log-component"
+ }
+ }
+
\ No newline at end of file
diff --git a/test/src/ts/pages/product2/productDetail.ts b/test/src/ts/pages/product2/productDetail.ts
new file mode 100644
index 0000000..a8b3093
--- /dev/null
+++ b/test/src/ts/pages/product2/productDetail.ts
@@ -0,0 +1,18 @@
+
+import { formatTime } from '../../utils/util';
+import Product from './product.service';
+const productService = new Product();
+
+Page({
+ data: {
+ logs: [],
+ },
+ onLoad() {
+ this.setData({
+ logs: (wx.getStorageSync('logs') || []).map(function (log) {
+ return formatTime(new Date(log));
+ }),
+ productName: productService.getProductName()
+ });
+ }
+});
diff --git a/test/src/ts/pages/product2/productDetail.wxml b/test/src/ts/pages/product2/productDetail.wxml
new file mode 100644
index 0000000..137fbe3
--- /dev/null
+++ b/test/src/ts/pages/product2/productDetail.wxml
@@ -0,0 +1,6 @@
+
+
+
+ {{index + 1}}. {{log}} {{productName}}
+
+
diff --git a/test/src/ts/pages/product2/productDetail.wxss b/test/src/ts/pages/product2/productDetail.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/test/src/ts/pages/product2/productList.json b/test/src/ts/pages/product2/productList.json
new file mode 100644
index 0000000..828eb8d
--- /dev/null
+++ b/test/src/ts/pages/product2/productList.json
@@ -0,0 +1,6 @@
+{
+ "navigationBarTitleText": "分包列表2",
+ "usingComponents": {
+ "index-component": "../../components/index-component/index-component"
+ }
+}
\ No newline at end of file
diff --git a/test/src/ts/pages/product2/productList.ts b/test/src/ts/pages/product2/productList.ts
new file mode 100644
index 0000000..3b33532
--- /dev/null
+++ b/test/src/ts/pages/product2/productList.ts
@@ -0,0 +1,34 @@
+
+// import { flow } from 'lodash';
+
+// const delay = (t = 0) => new Promise((resolve) => setTimeout(resolve, t));
+import Product from './product.service';
+const productService = new Product();
+//获取应用实例
+const app = getApp(); // eslint-disable-line no-undef
+
+Page({
+ data: {
+ motto: 'Hello List',
+ userInfo: {},
+ },
+ //事件处理函数
+ bindViewTap() {
+ wx.navigateTo({
+ url: './productDetail',
+ });
+ },
+ onLoad() {
+
+ // await delay();
+
+ // const log = flow(() => {
+ // console.log('onLoad');
+ // });
+
+ // log();
+ this.setData({
+ productName: productService.getProductName()
+ })
+ },
+});
diff --git a/test/src/ts/pages/product2/productList.wxml b/test/src/ts/pages/product2/productList.wxml
new file mode 100644
index 0000000..c2348bf
--- /dev/null
+++ b/test/src/ts/pages/product2/productList.wxml
@@ -0,0 +1,11 @@
+
+
+
+ {{motto}}
+
+
+ click me and go to detail page
+
+
+
+
diff --git a/test/src/ts/pages/product2/productList.wxss b/test/src/ts/pages/product2/productList.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/test/test.js b/test/test.js
index 5b666b2..18c96c7 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,4 +1,3 @@
-
import rimraf from 'rimraf';
import { execSync } from 'child_process';
import { resolve } from 'path';
@@ -14,10 +13,15 @@ const createTest = function createTest(ext) {
TEST_EXT: ext,
},
});
- stdout && console.log(stdout);
- }
- catch (err) {
- err.stdout && console.error(err.stdout);
+
+ if (stdout) {
+ console.log(stdout);
+ }
+ } catch (err) {
+ if (err.stdout) {
+ console.error(err.stdout);
+ }
+
expect(err).toBe(undefined);
}
@@ -29,11 +33,20 @@ const createTest = function createTest(ext) {
require(`./dist/${ext}/app`);
require(`./dist/${ext}/pages/index/index`);
require(`./dist/${ext}/pages/logs/logs`);
+ require(`./dist/${ext}/pages/product/productDetail`);
+ require(`./dist/${ext}/pages/product/productList`);
+ require(`./dist/${ext}/pages/product2/productDetail`);
+ require(`./dist/${ext}/pages/product2/productList`);
expect(global.App.mock.calls.length).toBe(1);
- expect(global.Page.mock.calls.length).toBe(2);
+ expect(global.Page.mock.calls.length).toBe(6);
+
+ const getVendorPath = path => resolve(__dirname, path, 'common.js');
+ expect(existsSync(getVendorPath(`dist/${ext}/pages/product`))).toBe(true);
+ expect(existsSync(getVendorPath(`dist/${ext}/pages/product2`))).toBe(true);
+ expect(existsSync(getVendorPath(`dist/${ext}`))).toBe(true);
- const inImagesDir = (name) => resolve(__dirname, `dist/${ext}/images`, name);
+ const inImagesDir = name => resolve(__dirname, `dist/${ext}/images`, name);
expect(existsSync(inImagesDir('wechat.png'))).toBe(true);
expect(existsSync(inImagesDir('wechat_selected.png'))).toBe(true);
expect(existsSync(inImagesDir('twitter.png'))).toBe(true);