Skip to content

Commit f3db2cc

Browse files
committed
feat: support babel cache and typescript cache, default true
1 parent 76a597a commit f3db2cc

11 files changed

Lines changed: 169 additions & 14 deletions

File tree

config/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ exports.config = {
88
buildPath: 'public',
99
publicPath: '/public/',
1010
hashLength: 8,
11+
cache: true,
1112
alias: {},
1213
packs: {},
1314
cdn: {},

config/loader.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ exports.babel = {
44
enable: true,
55
test: /\.jsx?$/,
66
exclude: /node_modules/,
7-
use: [
8-
{
9-
loader: 'babel-loader'
7+
use() {
8+
const loader = 'babel-loader'
9+
if (this.config.cache) {
10+
return [this.createCacheLoader(loader, this.config.cache)];
1011
}
11-
]
12+
return [loader];
13+
}
1214
};
1315

1416
exports.eslint = {
@@ -23,7 +25,14 @@ exports.typescript = {
2325
enable: false,
2426
test: /\.ts$/,
2527
exclude: [/node_modules/],
26-
use: ['ts-loader']
28+
use() {
29+
const loaders = ['ts-loader'];
30+
if(this.config.cache) {
31+
const cacheLoader = this.createCacheLoader('cache-loader', this.config.cache);
32+
loaders.unshift(cacheLoader);
33+
}
34+
return loaders;
35+
}
2736
};
2837

2938
exports.tslint = {

lib/base.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,9 @@ class WebpackBaseBuilder extends Config {
240240
if (Array.isArray(itemLoader.use)) {
241241
itemLoader.use.forEach((loader, index) => {
242242
const label = this.utils.getLoaderLabel(loader);
243-
const options = this.merge(loaderOptions[label], { options: itemLoader.options });
243+
const mLabel = this.loaderKeyLabelMapping[name];
244+
const configOptions = itemLoader.options && (label === mLabel || label === name) ? itemLoader.options : {};
245+
const options = this.merge(loaderOptions[label], { options: configOptions });
244246
if (this.utils.isString(loader)) {
245247
itemLoader.use.splice(index, 1, this.merge({ loader }, options));
246248
} else if (this.utils.isObject(loader) && this.utils.isString(loader.loader)) {
@@ -484,6 +486,12 @@ class WebpackBaseBuilder extends Config {
484486
return { loader: 'postcss-loader', options };
485487
}
486488

489+
createCacheLoader(loader, cacheOptions) {
490+
const cacheDirectory = this.utils.getCacheLoaderInfoPath(loader, this.env);
491+
const options = this.utils.isObject(cacheOptions) ? this.merge({ cacheDirectory }, cacheOptions) : { cacheDirectory };
492+
return { loader, options };
493+
}
494+
487495
createDllPlugin(dll) {
488496
dll = dll || this.config.dll;
489497
const dllArray = WebpackBaseBuilder.getDllConfig(dll);

lib/builder.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ exports.getDllWebpackConfig = (config, option = {}) => {
3939
const prefix = config.prefix;
4040
const resolveLoader = config.resolveLoader;
4141
const cdn = config.cdn;
42+
const cache = config.cache;
4243
const configLoaders = config.loaders || {};
4344
const configPlugins = config.plugins || {};
4445
const loaders = {};
@@ -56,7 +57,7 @@ exports.getDllWebpackConfig = (config, option = {}) => {
5657
}
5758
}
5859
dllArray.forEach(item => {
59-
const builderConfig = Object.assign({}, dllConfig, { prefix, entry: {}, dll: item, publicPath, buildPath, alias, externals, resolveLoader, install, cdn, loaders, plugins }, item.webpackConfig);
60+
const builderConfig = Object.assign({}, dllConfig, { cache, prefix, entry: {}, dll: item, publicPath, buildPath, alias, externals, resolveLoader, install, cdn, loaders, plugins }, item.webpackConfig);
6061
if (option.onlyView || utils.checkDllUpdate(config, item)) {
6162
dllWebpackConfig.push(new WebpackDllBuilder(builderConfig).create());
6263
}

lib/config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ class Config {
2424
'context', 'target', 'node', 'output', 'externals', 'resolve', 'watch', 'watchOptions', 'amd',
2525
'resolveLoader', 'devServer', 'performance', 'module', 'cache', 'profile', 'stats', 'cache', 'optimization'
2626
];
27+
this.loaderKeyLabelMapping = {
28+
scss: 'sass',
29+
typescript: 'ts',
30+
urlimage: 'url',
31+
urlmedia: 'url',
32+
urlfont: 'url',
33+
nunjucks: 'nunjucks-html'
34+
};
2735
this.logger = new Logger(config.logger, this);
2836
this.adapter = new Adapter(this);
2937
this.initialize(config);

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "easywebpack",
3-
"version": "4.0.7",
3+
"version": "4.1.0",
44
"description": "基于 Webpack 的前端构建工程化解决方案",
55
"keywords": [
66
"webpack",
@@ -15,6 +15,7 @@
1515
"babel-core": "^6.26.0",
1616
"babel-eslint": "^8.0.3",
1717
"babel-loader": "^7.1.2",
18+
"cache-loader": "^1.2.2",
1819
"chalk": "^2.0.1",
1920
"cross-spawn": "^5.1.0",
2021
"css-loader": "^0.28.4",

test/base.test.js

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const webpack = WebpackTool.webpack;
55
const merge = WebpackTool.merge;
66
const WebpackBaseBuilder = require('../lib/base');
77
const path = require('path').posix;
8-
8+
const utils = require('../utils/utils');
99
// http://chaijs.com/api/bdd/
1010
function createBuilder(config) {
1111
const builder = new WebpackBaseBuilder(config);
@@ -16,7 +16,14 @@ function createBuilder(config) {
1616
});
1717
return builder;
1818
}
19-
19+
function getLoaderByName(name, rules) {
20+
const loaderName = `${name}-loader`;
21+
return rules.filter(rule => {
22+
return rule.use.some(loader => {
23+
return loaderName === loader || (typeof loader === 'object' && loader.loader === loaderName);
24+
});
25+
});
26+
}
2027
describe('base.test.js', () => {
2128
before(() => {
2229
});
@@ -106,5 +113,50 @@ describe('base.test.js', () => {
106113
expect(webpackConfig.output.filename).to.equal('static/js/[name].js');
107114
expect(webpackConfig.output.chunkFilename).to.equal('static/js/chunk/[name].js');
108115
});
116+
describe('#webpack cache loader test', () => {
117+
it('should create babel cache loader disable test', () => {
118+
const builder = createBuilder({
119+
cache: false,
120+
});
121+
const webpackConfig = builder.create();
122+
const cacheLoader = getLoaderByName('cache', webpackConfig.module.rules);
123+
expect(cacheLoader.length).to.equal(0);
124+
});
125+
it('should create babel typescript cache loader test', () => {
126+
const cacheDirectory = utils.getCacheLoaderInfoPath('cache-loader')
127+
const builder = createBuilder({
128+
loaders:{
129+
typescript: true
130+
}
131+
});
132+
const webpackConfig = builder.create();
133+
const cacheLoader = getLoaderByName('cache', webpackConfig.module.rules);
134+
expect(cacheLoader.length).to.equal(1);
135+
expect(cacheLoader[0].use.length).to.equal(2);
136+
expect(cacheLoader[0].use[0].loader).to.equal('cache-loader');
137+
expect(cacheLoader[0].use[0].options.cacheDirectory).to.equal(cacheDirectory);
138+
expect(cacheLoader[0].use[1].loader).to.equal('ts-loader');
139+
});
140+
it('should create babel typescript config test', () => {
141+
const cacheDirectory = utils.getCacheLoaderInfoPath('cache-loader')
142+
const builder = createBuilder({
143+
loaders:{
144+
typescript: {
145+
options:{
146+
configFile: __dirname
147+
}
148+
}
149+
}
150+
});
151+
const webpackConfig = builder.create();
152+
const cacheLoader = getLoaderByName('cache', webpackConfig.module.rules);
153+
expect(cacheLoader.length).to.equal(1);
154+
expect(cacheLoader[0].use.length).to.equal(2);
155+
expect(cacheLoader[0].use[0].loader).to.equal('cache-loader');
156+
expect(cacheLoader[0].use[0].options.cacheDirectory).to.equal(cacheDirectory);
157+
expect(cacheLoader[0].use[1].loader).to.equal('ts-loader');
158+
expect(cacheLoader[0].use[1].options.configFile).to.equal(__dirname);
159+
});
160+
});
109161
});
110162
});

test/client.test.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ describe('client.test.js', () => {
341341
const tsLoader = getLoaderByName('ts', webpackConfig.module.rules);
342342
const eslint = getLoaderByName('eslint', webpackConfig.module.rules);
343343
const tslint = getLoaderByName('tslint', webpackConfig.module.rules);
344-
expect(tsLoader.use[0].loader).to.equal('ts-loader');
344+
expect(tsLoader.use[0].loader).to.equal('cache-loader');
345+
expect(tsLoader.use[1].loader).to.equal('ts-loader');
345346
expect(eslint.use[0].loader).to.equal('eslint-loader');
346347
expect(tslint.use[0].loader).to.equal('tslint-loader');
347348
expect(webpackConfig.resolve.extensions).to.include.members(['.ts', '.js']);
@@ -364,8 +365,9 @@ describe('client.test.js', () => {
364365
const tslint = getLoaderByName('tslint', webpackConfig.module.rules);
365366
expect(eslint).to.be.undefined;
366367
expect(tslint.use[0].loader).to.equal('tslint-loader');
367-
expect(tsLoader.use[0].loader).to.equal('ts-loader');
368-
expect(tsLoader.use[0].options.configFile).to.equal(configFile);
368+
expect(tsLoader.use[0].loader).to.equal('cache-loader');
369+
expect(tsLoader.use[1].loader).to.equal('ts-loader');
370+
expect(tsLoader.use[1].options.configFile).to.equal(configFile);
369371
});
370372

371373
it('should tslint enable test', () => {
@@ -383,6 +385,7 @@ describe('client.test.js', () => {
383385
const configFile = path.resolve(process.cwd(), './app/web/tsconfig.json');
384386
const builder = createBuilder({
385387
egg: true,
388+
cache: false,
386389
loaders:{
387390
typescript: true
388391
}

test/loader.test.js

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const expect = require('chai').expect;
33
const WebpackTool = require('webpack-tool');
44
const webpack = WebpackTool.webpack;
55
const merge = WebpackTool.merge;
6+
const utils = require('../utils/utils');
67
const WebpackBaseBuilder = require('../lib/base');
78
const WebpackClientBuilder = require('../lib/client');
89
const path = require('path').posix;
@@ -35,7 +36,14 @@ function getLoaderByName(name, rules) {
3536
});
3637
});
3738
}
38-
39+
function getLoadersByName(name, rules) {
40+
const loaderName = `${name}-loader`;
41+
return rules.filter(rule => {
42+
return rule.use.some(loader => {
43+
return loaderName === loader || (typeof loader === 'object' && loader.loader === loaderName);
44+
});
45+
});
46+
}
3947
function getLoaderByTest(test, rules) {
4048
return rules.find(rule => {
4149
return rule.test.toString() === test.toString();
@@ -81,6 +89,7 @@ describe('loader.test.js', () => {
8189

8290
it('should loader merge options test', () => {
8391
const config = {
92+
cache: false,
8493
loaders: {
8594
eslint: {
8695
options: {
@@ -262,6 +271,7 @@ describe('loader.test.js', () => {
262271
expect(vuehtml.use[0].loader).to.equal('vue-html-loader');
263272
expect(vuehtml.use[0].options.test).to.true;
264273
});
274+
265275

266276
describe('#webpack feature loader test', () => {
267277
it('should postcss-loader default config', () => {
@@ -305,4 +315,61 @@ describe('loader.test.js', () => {
305315
expect(postcssLoader.options.sourceMap).to.be.false;
306316
});
307317
});
318+
319+
describe('#webpack feature url loader test', () => {
320+
it('should url-loader default config', () => {
321+
const builder = createBuilder();
322+
const webpackConfig = builder.create();
323+
const urlLoaders = getLoadersByName('url', webpackConfig.module.rules);
324+
expect(urlLoaders.length).to.equal(3);
325+
});
326+
it('should url-loader default config', () => {
327+
const builder = createBuilder({
328+
loaders:{
329+
urlmedia:false,
330+
urlfont: false,
331+
urlimage: {
332+
options:{
333+
limit: 10000
334+
}
335+
}
336+
}
337+
});
338+
const webpackConfig = builder.create();
339+
const urlLoader = getLoaderByName('url', webpackConfig.module.rules);
340+
expect(urlLoader.use[0].options.limit).to.equal(10000);
341+
});
342+
});
343+
describe('#webpack babel loader test', () => {
344+
it('should babel-loader default config', () => {
345+
const cacheDirectory = utils.getCacheLoaderInfoPath('babel-loader', 'dev');
346+
const builder = createBuilder();
347+
const webpackConfig = builder.create();
348+
const babelLoader = getLoaderByName('babel', webpackConfig.module.rules);
349+
expect(babelLoader.use.length).to.equal(1);
350+
expect(babelLoader.use[0].options.cacheDirectory).to.equal(cacheDirectory);
351+
});
352+
});
353+
describe('#webpack config cache test', () => {
354+
it('should config cache false config', () => {
355+
const cacheDirectory = utils.getCacheLoaderInfoPath('babel-loader', 'dev');
356+
const builder = createBuilder({
357+
cache: false
358+
});
359+
const webpackConfig = builder.create();
360+
const babelLoader = getLoaderByName('babel', webpackConfig.module.rules);
361+
expect(babelLoader.use.length).to.equal(1);
362+
expect(babelLoader.use[0].options.cacheDirectory).to.be.undefined
363+
});
364+
it('should config cache undefined config', () => {
365+
const cacheDirectory = utils.getCacheLoaderInfoPath('babel-loader', 'dev');
366+
const builder = createBuilder({
367+
cache: undefined
368+
});
369+
const webpackConfig = builder.create();
370+
const babelLoader = getLoaderByName('babel', webpackConfig.module.rules);
371+
expect(babelLoader.use.length).to.equal(1);
372+
expect(babelLoader.use[0].options.cacheDirectory).to.equal(cacheDirectory);
373+
});
374+
});
308375
});

test/server.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ describe('server.test.js', () => {
125125
it('should typescript config test', () => {
126126
const configFile = path.resolve(__dirname, './app/web/tsconfig.json');
127127
const builder = createBuilder({
128+
cache: false,
128129
loaders:{
129130
typescript: {
130131
options:{

0 commit comments

Comments
 (0)