Skip to content

Commit

Permalink
Added an option to select a custom context to match moment-timezone l…
Browse files Browse the repository at this point in the history
…ocation. Fixes gilmoreorless#32.
  • Loading branch information
diniciacci committed Jan 29, 2021
1 parent 1b26de3 commit dc772b7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ For this reason, it’s probably safer to provide only one of `matchZones` or `m
There is also one non-filtering option that can be provided to configure other behaviour.

* `cacheDir` _(string)_ — A path where the generated files will be cached. If not provided, the files will be cached in an automatically-generated location.
* `momentTimezoneContext` _(regexp)_ — A regexp matching a context where `moment-timezone` is located. The timezone file will be replaced only if it is located in this context. Other instances of the timezone file out of this context will not be touched. This is useful in case you are using a version stored outside of `node_modules` (e.g. if module or vendor directory is `vendor\moment-timezone` the context could be matched for example with `vendor[\\/]moment-timezone$`). Defaults to `/node_modules[\\/]moment-timezone$/`.

### Version support

Expand Down
21 changes: 12 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function throwInvalid(message) {

function validateOptions(options) {
const filteringOptions = ['matchZones', 'matchCountries', 'startYear', 'endYear'];
const otherOptions = ['cacheDir'];
const otherOptions = ['cacheDir', 'momentTimezoneContext'];
const knownOptions = filteringOptions.concat(otherOptions);
const optionNames = Object.keys(options);
let usedFilteringOptions = [];
Expand Down Expand Up @@ -174,14 +174,16 @@ function validateOptions(options) {
}
});

// Invalid cache dir (not a valid path)
if ('cacheDir' in options) {
try {
path.parse(options.cacheDir);
} catch (error) {
throwInvalid(`Provided cacheDir is an invalid path: '${options.cacheDir}'`);
// Check options that require a valid path
['cacheDir'].forEach(option => {
if (option in options) {
try {
path.parse(options[option]);
} catch (error) {
throwInvalid(`Provided ${option} is an invalid path: '${options[option]}'`);
}
}
}
});
}

function MomentTimezoneDataPlugin(options = {}) {
Expand All @@ -192,11 +194,12 @@ function MomentTimezoneDataPlugin(options = {}) {
const matchZones = options.matchZones || null;
const matchCountries = options.matchCountries || null;
const cacheDir = options.cacheDir || null;
const momentTimezoneContext = options.momentTimezoneContext || /node_modules[\\/]moment-timezone$/;

return new webpack.NormalModuleReplacementPlugin(
/data[\\/]packed[\\/]latest\.json$/,
resource => {
if (resource.context.match(/node_modules[\\/]moment-timezone$/)) {
if (resource.context.match(momentTimezoneContext)) {
const config = { matchZones, matchCountries, startYear, endYear };
const tzdata = require('moment-timezone/data/packed/latest.json');
const file = cacheFile(tzdata, config, cacheDir);
Expand Down
31 changes: 30 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('instantiation', () => {
);
});

// TOOD: Warn instead of throw?
// TODO: Warn instead of throw?
it('throws when called with no arguments', () => {
assert.throws(
() => new MomentTimezoneDataPlugin(),
Expand Down Expand Up @@ -400,4 +400,33 @@ describe('usage', () => {
assert(cachedFiles().length === 2);
});
});

describe('custom context', () => {

it('matches moment-timezone in the specified context', async () => {
const { data } = await buildWebpack({
startYear: 1700,
momentTimezoneContext: /node_modules[\\/]moment-timezone$/,
});
const zoneCount = data.zones.length + data.links.length;
assert(zoneCount === moment.tz.names().length);
if (momentHasCountries) {
assert(data.countries.length === moment.tz.countries().length);
}
});

it('does not match moment-timezone when out of the specified context', async () => {
const { data } = await buildWebpack({
startYear: 1700,
momentTimezoneContext: /nonexistingdir[\\/]moment-timezone$/,
});
assert(data == null);
});

/* TODO: missing
it('matches moment-timezone only in the specified context', async () => {
});
*/

});
});
4 changes: 2 additions & 2 deletions test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ function buildWebpack(options) {
}

const module = Array.from(stats.compilation.modules).find(mod =>
rGeneratedFile.test(mod.request)
rGeneratedFile.test(mod.request) // Matches only if data processed (and cache generated)
);
const data = module.buildInfo.jsonData;
const data = module ? module.buildInfo.jsonData : null; // In case no processing happened

resolve({ stats, module, data });
});
Expand Down

0 comments on commit dc772b7

Please sign in to comment.