@wjunt/webpack-config
Version:
Presets of webpack config
208 lines (207 loc) • 7.35 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_logger_1 = require("@wjunt/node-logger");
const lodash_1 = require("lodash");
const path = require("path");
const utils_1 = require("../common/utils");
const common_1 = require("./common");
/**
* Support TypeScript/ES2017+ transpile.
* @example
* // Use default options.
* module.exports = merge({
* ts(),
* { ...others },
* });
* @example
* // Ignore js/jsx and exclude files in `node_modules`.
* module.exports = merge({
* ts({
* test: /\.tsx?$/,
* exclude: /node_modules/,
* }),
* { ...others },
* });
* @example
* // Enable type checking while bundling.
* module.exports = merge({
* ts({
* options: {
* transpileOnly: false,
* },
* }),
* { ...others },
* });
*/
function ts(_a = {}) {
var { feature } = _a, rule = __rest(_a, ["feature"]);
const tsImportPluginFactory = require('ts-import-plugin');
const beforeCustomTransformers = [];
const defaultOptions = {
configFile: 'tsconfig.json',
// @ts-ignore
compilerOptions: {
// @ts-ignore
module: 'esnext',
// @ts-ignore
moduleResolution: 'node',
sourceMap: true,
},
transpileOnly: true,
onlyCompileBundledFiles: true,
};
const featureSet = new Set(feature);
if (featureSet.has('vue')) {
defaultOptions.appendTsSuffixTo = [/\.vue$/];
beforeCustomTransformers.push(tsImportPluginFactory([
{
libraryName: '@wjunt/components',
style: (name) => {
const stylePath = path.normalize(`@wjunt/components/lib/theme/${path.basename(name, '.js')}.css`);
try {
/**
* Only import a style if exists.
* For example, fd-image has no style.
*/
require.resolve(stylePath, {
paths: [
process.cwd(),
],
});
return stylePath;
}
catch (_a) {
return '';
}
},
},
]));
}
if (featureSet.has('vue-jsx')) {
utils_1.checkDependency('@wjunt/typescript-vue-jsx-plugin');
const vueJsxTransformer = require('@wjunt/typescript-vue-jsx-plugin').vueJsxTransformer;
beforeCustomTransformers.push(vueJsxTransformer());
// @ts-ignore
defaultOptions.compilerOptions.jsx = 'react';
// @ts-ignore
defaultOptions.compilerOptions.jsxFactory = 'h';
}
if (featureSet.has('control-statements')) {
utils_1.checkDependency('tsx-control-statements');
const statements = require('tsx-control-statements').default;
beforeCustomTransformers.push(statements());
featureSet.add('react');
}
if (featureSet.has('antd')) {
beforeCustomTransformers.push(tsImportPluginFactory({
libraryDirectory: 'es',
libraryName: 'antd',
style: 'css',
}));
featureSet.add('react');
}
if (featureSet.has('material-ui')) {
beforeCustomTransformers.push(tsImportPluginFactory([
{
libraryName: '@material-ui/core',
libraryDirectory: 'esm',
style: false,
camel2DashComponentName: false,
},
{
libraryName: '@material-ui/icons',
libraryDirectory: 'esm',
style: false,
camel2DashComponentName: false,
},
]));
}
if (featureSet.has('react')) {
// @ts-ignore
defaultOptions.compilerOptions.jsx = 'react';
}
if (beforeCustomTransformers.length > 0) {
const getCustomTransformers = rule.options && rule.options.getCustomTransformers;
if (getCustomTransformers) {
if (typeof getCustomTransformers === 'string') {
throw new Error(`Conflict option "customTransformers" with type "string" found`);
}
delete rule.options.getCustomTransformers;
defaultOptions.getCustomTransformers = function (program) {
const customTransformers = getCustomTransformers(program);
return lodash_1.mergeWith({}, customTransformers, {
before: beforeCustomTransformers,
}, (value, srcValue) => {
if (Array.isArray(value) && Array.isArray(srcValue)) {
return value.concat(srcValue);
}
});
};
}
else {
defaultOptions.getCustomTransformers = () => ({
before: beforeCustomTransformers,
});
}
}
const loaders = [
{
loader: 'ts-loader',
options: lodash_1.defaultsDeep(rule.options, defaultOptions),
},
];
if (rule.cacheable !== false) {
const cacheLoaderOptions = typeof rule.cacheable === 'object' ? rule.cacheable : {};
if (typeof cacheLoaderOptions.cacheDirectory === 'undefined') {
cacheLoaderOptions.cacheDirectory = path.resolve('node_modules', '.cache', 'ts-loader');
}
if (typeof cacheLoaderOptions.cacheIdentifier === 'undefined') {
cacheLoaderOptions.cacheIdentifier = `cache-loader:ts-loader ${[...featureSet].sort()} ${process.env.NODE_ENV}`;
}
loaders.unshift(common_1.getCacheLoader(cacheLoaderOptions));
}
const config = utils_1.createWebpackConfiguration({
module: {
rules: [
common_1.combineRule(rule, {
test: /\.[tj]sx?$/,
use: loaders,
}),
],
},
resolve: {
extensions: ['.tsx', '.jsx', '.ts'],
},
});
if (featureSet.has('react')) {
try {
utils_1.checkDependency('react-hot-loader');
config.module.rules.push({
test: /\.[tj]sx?$/,
loader: 'react-hot-loader/webpack',
});
config.resolve.modules = utils_1.getResolveModules(path.resolve(__dirname, '../..'));
}
catch (e) {
if (e.message.startsWith('Required dependency')) {
node_logger_1.default.getLogger('fwc:ts').warn(`"react-hot-loader" is not installed, hot reload of React components is disabled.`);
}
else {
throw e;
}
}
}
return config;
}
exports.ts = ts;