Skip to content

Commit 61886d5

Browse files
committed
feat: loader.options support
1 parent d2e4eee commit 61886d5

8 files changed

Lines changed: 112 additions & 77 deletions

File tree

config/loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ exports.babel = {
66
exclude: /node_modules/,
77
use() {
88
const loaders = [];
9-
const compile = this.config.compile;
9+
const { compile = {} } = this.config;
1010
if (compile.thread) {
1111
loaders.unshift(this.createThreadLoader(compile.thread));
1212
}

lib/builder.js

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -83,65 +83,18 @@ exports.getBuilderConfig = (config = {}, option = {}) => {
8383
exports.getDllWebpackConfig = (config, option = {}) => {
8484
config.baseDir = config.baseDir || process.cwd();
8585
if (config.dll) {
86-
const dllWebpackConfig = [];
87-
const dllConfig = { env: config.env, baseDir: config.baseDir };
88-
const dllArray = WebpackDllBuilder.getDllConfig(config.dll);
89-
const alias = merge(config.alias, config.resolve && config.resolve.alias);
90-
const externals = config.externals;
91-
const node = config.node;
92-
const publicPath = config.publicPath;
93-
const buildPath = config.buildPath;
94-
const install = config.install;
95-
const prefix = config.prefix;
96-
const resolveLoader = config.resolveLoader;
97-
const cdn = config.cdn;
98-
const compile = config.compile || {};
99-
const host = config.host;
100-
const module = config.module;
101-
const configLoaders = config.loaders || {};
102-
const configPlugins = config.plugins || {};
103-
const optimization = config.optimization;
104-
const loaders = {};
105-
const plugins = {};
86+
const dll = WebpackDllBuilder.getDllConfig(config.dll);
10687
const cli = utils.isObject(config.cli) ? config.cli : {};
107-
if (utils.isObject(configLoaders) && configLoaders.typescript) {
108-
loaders.typescript = configLoaders.typescript;
109-
}
110-
// support cli size
111-
if (!Array.isArray(configPlugins)) {
112-
if (configPlugins.analyzer) {
113-
plugins.analyzer = configPlugins.analyzer;
114-
}
115-
if (configPlugins.stats) {
116-
plugins.stats = configPlugins.stats;
117-
}
118-
}
119-
dllArray.forEach(item => {
120-
const builderConfig = Object.assign({}, dllConfig, {
121-
host,
122-
node,
123-
compile,
124-
prefix,
125-
entry: {},
126-
dll: item,
127-
publicPath,
128-
buildPath,
129-
alias,
130-
externals,
131-
resolveLoader,
132-
install,
133-
cdn,
134-
module,
135-
loaders,
136-
plugins,
137-
optimization
138-
}, item.webpackConfig);
88+
const webpackConfigList = [];
89+
dll.forEach(item => {
90+
const tmpConfig = utils.cloneDeep(config);
91+
const dllConfig = merge(tmpConfig, { entry: null, dll: null }, { dll: item }, item.webpackConfig);
13992
if (option.onlyView || cli.dll || utils.checkDllUpdate(config, item)) {
140-
dllWebpackConfig.push(new WebpackDllBuilder(builderConfig).create());
93+
webpackConfigList.push(new WebpackDllBuilder(dllConfig).create());
14194
}
14295
});
143-
if (dllWebpackConfig.length) {
144-
return dllWebpackConfig.length === 1 ? dllWebpackConfig[0] : dllWebpackConfig;
96+
if (webpackConfigList.length) {
97+
return webpackConfigList.length === 1 ? webpackConfigList[0] : webpackConfigList;
14598
}
14699
} else {
147100
console.warn(`${chalk.red('[easywebpack] webpack config no dll config, please check webpack.config.js file config')}`);

lib/core/config.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ class Config {
8787
}
8888

8989
get buildPath() {
90-
return utils.normalizeBuildPath(this.config.buildPath, this.baseDir);
90+
const buildPath = this.utils.getOutputPath(this.config);
91+
return utils.normalizeBuildPath(buildPath, this.baseDir);
9192
}
9293

9394
get publicPath() {
94-
const config = this.config;
9595
const host = this.host;
96-
const publicPath = config.publicPath.replace(/\/$/, '');
96+
const publicPath = this.utils.getOutputPublicPath(this.config);
9797
if (this.utils.isHttpOrHttps(publicPath)) {
9898
return this.utils.normalizePublicPath(publicPath);
9999
}
@@ -106,7 +106,7 @@ class Config {
106106
get host() {
107107
let host = '';
108108
const config = this.config;
109-
const configPublicPath = config.publicPath.replace(/\/$/, '');
109+
const configPublicPath = this.utils.getOutputPublicPath(this.config);
110110
const cdnUrl = this.getPublicPathFromCDN(config.cdn).replace(/\/$/, '');
111111
if (cdnUrl) {
112112
if (cdnUrl.endsWith(configPublicPath)) {
@@ -172,11 +172,17 @@ class Config {
172172
if (this._loaderOptions) {
173173
return this._loaderOptions;
174174
}
175-
this._loaderOptions = this.merge(this.config.loaderOptions, this.loaders.options);
176-
return this._loaderOptions;
175+
const loader = this.getConfigLoaderByName('options');
176+
if (this.utils.isObject(loader)) {
177+
if (loader.hasOwnProperty('options')) {
178+
this._loaderOptions = loader.options;
179+
} else {
180+
this._loaderOptions = loader;
181+
}
182+
}
183+
return this._loaderOptions || {};
177184
}
178185

179-
180186
initZero(config) {
181187
if (this.egg) {
182188
zero.initEggDefault(config);
@@ -271,7 +277,7 @@ class Config {
271277
analysisWebpackConfig(config = {}) {
272278
const webpackConfig = {};
273279
this.webpackNodeList.forEach(key => {
274-
if (this.utils.has(config, key)) {
280+
if (config.hasOwnProperty(key)) {
275281
const value = this.utils.get(config, key);
276282
this.utils.set(webpackConfig, key, value);
277283
}
@@ -601,7 +607,7 @@ class Config {
601607
}
602608

603609
getPublicPathFromCDN(url, dynamicDir) {
604-
if (!this.dev && this.utils.has(url)) {
610+
if (!this.dev && url) {
605611
let cdnUrl = url;
606612
let cdnDir = dynamicDir;
607613
if (this.utils.isObject(url)) {
@@ -611,6 +617,7 @@ class Config {
611617
if (cdnUrl) {
612618
return cdnDir ? this.utils.joinPath(cdnUrl, cdnDir) : cdnUrl;
613619
}
620+
614621
}
615622
return '';
616623
}

lib/core/loader.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ module.exports = {
4646

4747
getLoaderByName(name) {
4848
const loader = this.getMergeLoaderByName(name);
49-
const options = this.merge(this.config.loaderOptions, this.loaders.options);
50-
const loaders = this.mergeLoaderOption(loader, options);
49+
const loaders = this.mergeLoaderOption(loader, this.loaderOptions);
5150
const webpackLoaders = this.createLoader(loaders);
5251
if (webpackLoaders.length) {
5352
return webpackLoaders[0];
@@ -80,7 +79,7 @@ module.exports = {
8079
const createTsLoader = options => {
8180
return { loader: 'ts-loader', options };
8281
};
83-
const compile = this.config.compile;
82+
const compile = this.config.compile || {};
8483
if (compile.thread) {
8584
loaders.unshift(this.createThreadLoader(compile.thread));
8685
loaders.push(createTsLoader({ happyPackMode: true }));
@@ -242,7 +241,13 @@ module.exports = {
242241
const label = this.getLoaderLabel(loader);
243242
const mLabel = this.loaderKeyLabelMapping[name];
244243
const configOptions = itemLoader.options && (label === mLabel || label === name) ? itemLoader.options : {};
245-
const options = this.merge(loaderOptions[label], { options: configOptions });
244+
const tmpLoaderOptions = loaderOptions[label] || {};
245+
if (tmpLoaderOptions.hasOwnProperty('include') || tmpLoaderOptions.hasOwnProperty('exclude')) {
246+
delete tmpLoaderOptions.include;
247+
delete tmpLoaderOptions.exclude;
248+
}
249+
const exOptions = tmpLoaderOptions.options ? tmpLoaderOptions : { options: tmpLoaderOptions };
250+
const options = this.merge(exOptions, { options: configOptions });
246251
if (this.utils.isString(loader)) {
247252
itemLoader.use.splice(index, 1, this.merge({ loader }, options));
248253
} else if (this.utils.isObject(loader) && this.utils.isString(loader.loader)) {
@@ -364,7 +369,7 @@ module.exports = {
364369
this.mergeLoader(loaders);
365370
this.mergeLoader(rules);
366371
this.prepareCssModuleLoader(this.loaders);
367-
this.prepareLoaderOption(this.loaders, this.merge(config.loaderOptions, this.loaders.options));
372+
this.prepareLoaderOption(this.loaders, this.loaderOptions);
368373
return this.installLoader(this.loaders);
369374
}
370375
};

lib/target/dll.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class WebpackDllBuilder extends WebpackBaseBuilder {
99
this.mergeConfig(dll);
1010
this.setBuildPath(this.utils.getDllCompileFileDir(this.env), true);
1111
this.setDevTool(config.devtool);
12-
this.setDllEntry(config.dll);
1312
this.setLibrary('[name]');
1413
this.setStartCreateQueue(this.setBabelENV);
1514
this.setCreateQueue(this.createDllPlugin);
@@ -19,8 +18,8 @@ class WebpackDllBuilder extends WebpackBaseBuilder {
1918
return true;
2019
}
2120

22-
setDllEntry(configDll) {
23-
const dllArray = WebpackDllBuilder.getDllConfig(configDll);
21+
createEntry(config) {
22+
const dllArray = WebpackDllBuilder.getDllConfig(config.dll);
2423
dllArray.forEach(item => {
2524
this.addEntry(item.name, item.lib);
2625
});

test/loader.test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,4 +371,57 @@ describe('loader.test.js', () => {
371371
expect(babelLoader.use[0].options.cacheDirectory).to.equal(cacheDirectory);
372372
});
373373
});
374+
375+
describe('#webpack loader options cache test', () => {
376+
it('should loader options', () => {
377+
const builder = createBuilder({ loaders: {
378+
babel: {
379+
include: __dirname,
380+
exclude: [__dirname]
381+
},
382+
options: { // 扩展配置
383+
babel: {
384+
options: {
385+
flag: 1
386+
}
387+
}
388+
}
389+
}});
390+
const webpackConfig = builder.create();
391+
const babelLoader = helper.getLoaderByName('babel', webpackConfig.module.rules);
392+
expect(babelLoader.include).to.equal(__dirname);
393+
expect(babelLoader.exclude[0]).to.equal(__dirname);
394+
expect(babelLoader.use[1].options.flag).to.equal(1);
395+
});
396+
});
397+
describe('#webpack loader options cache test', () => {
398+
it('should loader options', () => {
399+
const builder = createBuilder({
400+
module: {
401+
rules: [
402+
{ babel:
403+
{
404+
include: __dirname,
405+
exclude: [__dirname]
406+
}
407+
},
408+
{
409+
options: { // 扩展配置
410+
babel: {
411+
options: {
412+
flag: 1
413+
}
414+
}
415+
}
416+
}
417+
]
418+
}
419+
});
420+
const webpackConfig = builder.create();
421+
const babelLoader = helper.getLoaderByName('babel', webpackConfig.module.rules);
422+
expect(babelLoader.include).to.equal(__dirname);
423+
expect(babelLoader.exclude[0]).to.equal(__dirname);
424+
expect(babelLoader.use[1].options.flag).to.equal(1);
425+
});
426+
});
374427
});

test/vue.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ describe('vue.test.js', () => {
180180
const vueLoader = helper.getLoaderByName('vue', webpackConfig.module.rules);
181181
expect(vueLoader.use[0].options.loaders).to.include.keys(['ts', 'js', 'css']);
182182
});
183+
183184
it('should vue ts module rules native config test', () => {
184185
const builder = new WebpackServerBuilder({
185186
module: {
@@ -206,5 +207,6 @@ describe('vue.test.js', () => {
206207
const vueLoader = helper.getLoaderByName('vue', webpackConfig.module.rules);
207208
expect(vueLoader.use[0].options.loaders).to.include.keys(['ts', 'js', 'css']);
208209
});
210+
209211
});
210212
});

utils/utils.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ utils.joinPath = function() {
7979
}).join('/');
8080
};
8181

82+
utils.getOutputPath = config => {
83+
const { output = {}, buildPath } = config;
84+
if (output.path) {
85+
return output.path;
86+
}
87+
return buildPath;
88+
};
89+
90+
utils.getOutputPublicPath = config => {
91+
const { output = {}, publicPath } = config;
92+
if (output.publicPath) {
93+
return output.publicPath.replace(/\/$/, '');
94+
}
95+
return publicPath.replace(/\/$/, '');
96+
};
97+
8298
utils.getEntry = (config, type) => {
8399
const entry = config.entry;
84100
if (utils.isObject(entry) && (entry.loader || entry.include) || entry instanceof RegExp) {
@@ -278,9 +294,9 @@ utils.getLoaderLabel = (loader, ctx) => {
278294
loaderName = loader.name;
279295
} else if (loader.loader) {
280296
loaderName = loader.loader;
281-
} else if (Array.isArray(loader.use) || utils.isFunction(loader.use)) {
282-
const loaders = utils.isFunction(loader.use) ? loader.use.apply(ctx) : loader.use;
283-
loaderName = loaders.reduce((names, item) => {
297+
} else if (Array.isArray(loader.use)) {
298+
// const loaders = utils.isFunction(loader.use) ? loader.use.apply(ctx) : loader.use;
299+
loaderName = loader.use.reduce((names, item) => {
284300
if (utils.isString(item)) {
285301
names.push(item.replace(/-loader$/, ''));
286302
} else if (item.loader) {
@@ -292,7 +308,7 @@ utils.getLoaderLabel = (loader, ctx) => {
292308
loaderName = Object.keys(loader)[0];
293309
}
294310
}
295-
return loaderName.replace(/-loader$/, '');
311+
return utils.isString(loaderName) && loaderName.replace(/-loader$/, '');
296312
};
297313

298314
utils.loadNodeModules = isCache => {

0 commit comments

Comments
 (0)