@ices/locale-webpack-plugin
Version:
webpack plugin for parsing locale files
116 lines • 4.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fs_1 = tslib_1.__importDefault(require("fs"));
const path_1 = tslib_1.__importDefault(require("path"));
const vm_1 = tslib_1.__importDefault(require("vm"));
const babel = tslib_1.__importStar(require("@babel/core"));
const loader_utils_1 = require("loader-utils");
const utils_1 = require("../lib/utils");
const createHashName_1 = tslib_1.__importDefault(require("../lib/createHashName"));
const merge_1 = tslib_1.__importDefault(require("../lib/merge"));
const resource_1 = tslib_1.__importDefault(require("../lib/resource"));
const cwd = fs_1.default.realpathSync(process.cwd());
const runtimeModulePath = path_1.default.join(__dirname, '../lib/runtime');
/**
* 加载数据
*/
function loadData(file) {
const source = (this.fs || fs_1.default).readFileSync(file);
const { warnings, locale, data } = (0, resource_1.default)(source, file);
for (const warn of warnings) {
this.emitWarning(warn);
}
return (0, merge_1.default)([{ locale, data }]);
}
/**
* 转换代码。
*/
function transformCode(originalCode) {
const res = babel.transform(originalCode, {
babelrc: false,
configFile: false,
sourceType: 'unambiguous',
filename: 'x.js',
presets: [
[
require('@babel/preset-env'),
{
modules: 'commonjs',
targets: { node: 'current' },
},
],
],
});
const code = res ? res.code : '';
if (typeof code !== 'string') {
return '';
}
return code;
}
function isRuntimeModule(file) {
return runtimeModulePath === file || `${runtimeModulePath}.js` === file;
}
/**
* 执行模块代码,获取导出结果及依赖信息
*/
function evalModuleCode(code) {
const dependencies = new Set();
const module = { exports: {} };
const vmContext = vm_1.default.createContext({
module,
exports: module.exports,
require: (file) => {
file = file.split(/[!|]/).pop().replace(/\?.*/, '');
file = path_1.default.isAbsolute(file) ? file : path_1.default.join(this.context, file);
if (isRuntimeModule(file)) {
dependencies.add(file.replace(/(?:\.js)?$/, '.js'));
return require(file);
}
dependencies.add(file);
// 模块内容由内部插件生成,所以解析是确定的
// 不会有嵌套超过一层的导入
// 所以这里可以直接使用loadData进行数据加载
return loadData.call(this, file);
},
});
vm_1.default.runInContext(transformCode(code), vmContext, {
displayErrors: true,
breakOnSigint: true,
});
const exports = module.exports;
return {
exports: exports && exports.__esModule ? exports.default : exports,
dependencies,
};
}
async function getModuleCode(source, options) {
const { exports, dependencies } = evalModuleCode.call(this, source);
const { resourcePath } = this;
this.clearDependencies();
if (options.mode === 'development') {
this.addDependency(resourcePath);
for (const deps of dependencies) {
this.addDependency(deps);
}
}
const { extractor } = options;
const hash = (0, createHashName_1.default)(resourcePath, 6);
const code = await extractor.extract(exports, hash);
return `
/** ${(0, utils_1.normalizePath)(resourcePath, cwd)} (extracted) **/
${code}
`;
}
const extractLoader = function (source) {
const options = (0, loader_utils_1.getOptions)(this);
this.cacheable(true);
const callback = this.async() || (() => { });
getModuleCode
.call(this, Buffer.isBuffer(source) ? source.toString('utf8') : source, options)
.then((code) => callback(null, code))
.catch(callback);
};
extractLoader.filepath = __filename;
exports.default = extractLoader;
//# sourceMappingURL=extractLoader.js.map