feat: add filer webpack plugin

This commit is contained in:
Ben Heidemann 2021-04-04 01:22:28 +01:00 committed by David Humphrey
parent fd90f32d4c
commit d040763a73
4 changed files with 173 additions and 0 deletions

View File

@ -0,0 +1,88 @@
var path = require('path');
var utils = require('./utils');
const PLUGIN_NAME = 'filer-webpack-plugin';
const OPTIONS_SCHEMA = require('./schema');
const OPTIONS_PROCESSORS = require('./processors');
module.exports = class FilerWebpackPlugin {
constructor(options = {}) {
utils.validateOptions(options, OPTIONS_SCHEMA);
this.options = utils.processOptions(options, OPTIONS_PROCESSORS);
}
apply(compiler) {
compiler.hooks.normalModuleFactory.tap(
PLUGIN_NAME,
(factory) => {
factory.hooks.resolve.tap(
PLUGIN_NAME,
(resolveData) => {
// Resolve fsProvider if required
if (
resolveData.request === 'fsProvider'
&& resolveData.context === this.options.shimsDir
) {
return this.resolveFsProvider(resolveData);
}
// Ignore filer files (these should resolve modules normally)
if (resolveData.context.startsWith(this.options.filerDir)) return;
// Apply fs, path and buffer shims if required
switch (resolveData.request) {
case 'fs':
if (!this.options.shimFs) return;
return this.applyFsShim(resolveData);
case 'path':
if (!this.options.shimPath) return;
return this.applyPathShim(resolveData);
case 'buffer':
if (!this.options.shimBuffer) return;
return this.applyBufferShim(resolveData);
default:
return;
}
}
);
},
)
}
resolveFsProvider(resolveData) {
switch (this.options.fsProvider) {
case 'default':
resolveData.request = path.join(this.options.fsProviderDir, 'default.js');
break;
case 'indexeddb':
resolveData.request = path.join(this.options.fsProviderDir, 'indexeddb.js');
break;
case 'memory':
resolveData.request = path.join(this.options.fsProviderDir, 'memory.js');
break;
case 'custom':
resolveData.request = path.join(this.options.fsProviderDir, 'custom.js');
break;
default:
throw new Error([
`Invalid option for fsProvider.`,
`fsProvider must be one of 'default', 'indexeddb', 'memory' or 'custom'.`,
`If using a custom fsProvider, you must also provide the fsProviderDir option.`
].join(' '));
}
}
applyFsShim(resolveData) {
resolveData.request = path.join(this.options.shimsDir, 'fs.js');
}
applyPathShim(resolveData) {
resolveData.request = path.join(this.options.shimsDir, 'path.js');
}
applyBufferShim(resolveData) {
resolveData.request = path.join(this.options.shimsDir, 'buffer.js');
}
}

View File

@ -0,0 +1,33 @@
const ROOT_DIR_TAG = '<rootDir>';
const CWD = process.cwd();
module.exports = {
filerDir: {
process: function(value) {
if (!value) {
return path.join(CWD, 'node_modules', 'filer');
}
return value.replace(ROOT_DIR_TAG, CWD);
},
},
shimsDir: {
process: function(value) {
if (!value) {
return path.join(CWD, 'node_modules', 'filer', 'shims');
}
return value.replace(ROOT_DIR_TAG, CWD);
}
},
shimFs: { default: true },
shimPath: { default: true},
shimBuffer: { default: true},
fsProvider: { default: 'default'},
fsProviderDir: {
process: function(value) {
if (!value) {
return path.join(CWD, 'node_modules', 'filer', 'shims', 'providers');
}
return value.replace(ROOT_DIR_TAG, CWD);validateOptions
},
},
};

View File

@ -0,0 +1,26 @@
module.exports = {
type: 'object',
properties: {
filerDir: {
type: 'string',
},
shimsDir: {
type: 'string',
},
shimFs: {
type: 'boolean',
},
shimPath: {
type: 'boolean',
},
shimBuffer: {
type: 'boolean',
},
fsProvider: {
type: 'string',
},
fsProviderDir: {
type: 'string',
},
}
};

View File

@ -0,0 +1,26 @@
var { validate } = require('schema-utils');
function validateOptions(options, schema) {
validate(schema, options);
}
function processOptions(options, processors) {
const processedOptions = {};
for (const [property, processor] of Object.entries(processors)) {
processedOptions[property] = options[property];
if (processedOptions[property] === undefined) {
processedOptions[property] = processor.default;
}
if (processor.process) {
processedOptions[property] = processor.process(processedOptions[property]);
}
}
return processedOptions;
}
module.exports = {
validateOptions,
processOptions,
};