lincd-cli
Version:
Command line tools for the lincd.js library
444 lines • 19.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateWebpackConfig = generateWebpackConfig;
const declaration_plugin_1 = __importDefault(require("./plugins/declaration-plugin"));
const externalise_modules_1 = __importDefault(require("./plugins/externalise-modules"));
const watch_run_1 = __importDefault(require("./plugins/watch-run"));
const utils_1 = require("./utils");
const colors = __importStar(require("colors"));
// console.log('Webpack '+require('webpack/package.json').version);
// console.log('ts-loader '+require('ts-loader/package.json').version);
const fs_1 = __importDefault(require("fs"));
const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
const webpack_1 = __importDefault(require("webpack"));
const path_1 = __importDefault(require("path"));
// const WebpackLicencePlugin = require('webpack-license-plugin');
// const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const webpack_bundle_analyzer_1 = require("webpack-bundle-analyzer");
const terser_webpack_plugin_1 = __importDefault(require("terser-webpack-plugin"));
const child_process_1 = require("child_process");
const copy_webpack_plugin_1 = __importDefault(require("copy-webpack-plugin"));
const NODE_ENV = process.env.NODE_ENV;
const nodeProduction = NODE_ENV == 'production';
// const libraryName = 'lincd';
process.traceDeprecation = true;
function getLincdPackagePaths(packages) {
if (!packages) {
let pkgJson = (0, utils_1.getPackageJSON)();
packages = { ...pkgJson.dependencies, ...pkgJson.devDependencies };
}
let lincdPackagePaths = [];
for (var dependency of Object.keys(packages)) {
try {
let pkgJson = require(dependency + '/package.json');
if (pkgJson.lincd) {
let pkgPath = require.resolve(dependency + '/package.json');
lincdPackagePaths.push(pkgPath.substring(0, pkgPath.length - 13));
}
}
catch (err) {
// console.log("could not find "+dependency);
}
}
return lincdPackagePaths;
}
function generateWebpackConfig(buildName, moduleName, config = {}) {
if (!config.externals)
config.externals = {};
if (!config.internals)
config.internals = [];
var watch = config.watch;
var productionMode = nodeProduction || config.productionMode;
var es5 = config.target == 'es5';
var es6 = config.target == 'es6';
//remove the scope (used for filenames for example)
var cleanModuleName = moduleName.replace(/@[\w\-]+\//, '');
var configFile;
if (es5 && fs_1.default.existsSync('tsconfig-es5.json')) {
configFile = 'tsconfig-es5.json';
}
else {
configFile = 'tsconfig.json';
}
if (!fs_1.default.existsSync(configFile)) {
(0, utils_1.warn)('Cannot find ' + configFile);
process.exit();
}
let tsConfig = JSON.parse(fs_1.default.readFileSync(configFile, 'utf8'));
var plugins = [
// new webpack.DefinePlugin({
// 'process.env.BROWSER': JSON.stringify(true),
// 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
// }),
// new webpack.NoEmitOnErrorsPlugin(),
// new ExtractTextPlugin(config.cssFileName ? config.cssFileName : cleanModuleName + '.css'),
new mini_css_extract_plugin_1.default({
// linkType: false,
filename: config.cssFileName
? config.cssFileName
: cleanModuleName + '.css',
}),
//currently not compatible with webpack 5
// new WebpackLicencePlugin({
// excludedPackageTest: (packageName, version) => {
// return packageName.indexOf('lincd') !== -1;
// },
// }),
//NOTE: grunt comes with a copy task, which is ran during `yarn lincd build` but cannot run during `yarn lincd dev`
//so here we ALSO copy the same files to cover dev flow
new copy_webpack_plugin_1.default({
patterns: [
{
from: 'src/**/*.scss',
to({ context, absoluteFilename }) {
// console.log(chalk.magenta(context),chalk.magenta(absoluteFilename),process.cwd());
//turn absolute path into the right lib path (lib is NOT in webpack output path, so need to use '../')
let outputPath = absoluteFilename
.replace(process.cwd(), '')
.replace('/src/', '../lib/');
// console.log(chalk.blueBright(outputPath));
return Promise.resolve(outputPath);
},
noErrorOnMissing: true,
},
],
}),
];
if (config.debug) {
plugins.push(new watch_run_1.default());
}
if (config.afterBuildCommand || config.afterFirstBuildCommand) {
let executedFirstCommand = false;
plugins.push({
apply: (compiler) => {
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
if (config.afterBuildCommand) {
(0, child_process_1.exec)(config.afterBuildCommand, (err, stdout, stderr) => {
if (stdout)
process.stdout.write(stdout);
if (stderr)
process.stderr.write(stderr);
});
}
if (config.afterFirstBuildCommand && !executedFirstCommand) {
executedFirstCommand = true;
(0, child_process_1.exec)(config.afterFirstBuildCommand, (err, stdout, stderr) => {
if (stdout)
process.stdout.write(stdout);
if (stderr)
process.stderr.write(stderr);
});
}
});
},
});
}
if (config.analyse) {
plugins.push(new webpack_bundle_analyzer_1.BundleAnalyzerPlugin());
}
if ((es6 || config.declarations === true) && !config.declarations === false) {
plugins.push(new declaration_plugin_1.default({
out: (config.filename ? config.filename : cleanModuleName) + '.d.ts',
root: config.outputPath ? config.outputPath : './lib/',
debug: 'debug' in config ? config.debug : false,
}));
}
// var resolvePlugins = [
// new TsconfigPathsPlugin({
// configFile: configFile,
// silent: true,
// }),
// ];
var aliases = config.alias || {};
let postcssPlugins = [];
if (!config.cssMode) {
config.cssMode = 'mixed';
}
if (config.cssMode === 'scss-modules' ||
config.cssMode === 'scss' ||
config.cssMode === 'mixed') {
postcssPlugins = postcssPlugins.concat([
'postcss-preset-env',
productionMode && 'cssnano',
]);
//we once had:
// 'postcss-import': {},
// // 'postcss-cssnext': {},
// 'postcss-nested': {},
// // "postcss-scss": {}, //<-- only add this back if the build gets stuck on //comments in scss files, but I dont think that will be the case anymore
if (config.cssMode === 'scss-modules' || config.cssMode === 'mixed') {
postcssPlugins.push([
'postcss-modules',
{
generateScopedName: utils_1.generateScopedName.bind(null, config.prod, true),
globalModulePaths: [
/tailwind/,
/tailwindcss/,
config.cssGlobalModulePaths,
].filter(Boolean),
},
]);
}
}
if (config.cssMode === 'tailwind' || config.cssMode === 'mixed') {
let lincdPackagePaths;
//IF this package is including sources from another lincd package in its bundle (usually not the case)
if (config.internals) {
//THEN make sure that we also look for tailwind classes in those packages
//pass the list of internal packages, or if all, pass null because it will look up all the package.json:dependencies
lincdPackagePaths = getLincdPackagePaths(config.internals !== '*' ? config.internals : null).map((path) => {
return path + '/lib/**/*.{js,mjs}';
});
}
// console.log(chalk.blueBright('tailwind content: ')+chalk.magenta(['./frontend/src/**/*.{tsx,ts}',...lincdPackagePaths]));
postcssPlugins.push([
'tailwindcss',
{
content: ['./src/**/*.{tsx,ts}', ...lincdPackagePaths],
safelist: productionMode
? {}
: {
//in development mode we allow all classes here, so that you can easily develop
pattern: /./,
variants: ['sm', 'md', 'lg', 'xl', '2xl'],
},
theme: {
extend: {
colors: (0, utils_1.getLinkedTailwindColors)(),
},
},
plugins: [
// tailwindPlugin(function ({addBase, config}) {
//we can use LINCD CSS variables for default font color, size etc.
// addBase({
// 'h1': { fontSize: config('theme.fontSize.2xl') },
// 'h2': { fontSize: config('theme.fontSize.xl') },
// 'h3': { fontSize: config('theme.fontSize.lg') },
// })
// }),
],
},
]);
}
let rules = [
{
test: /\.(scss|css)$/,
use: [
mini_css_extract_plugin_1.default.loader,
{
loader: 'css-loader',
options: {
url: false,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: postcssPlugins,
},
},
},
{
loader: 'sass-loader',
options: { sourceMap: true },
},
],
},
// {
// test: /\.(ts|tsx)$/,
// exclude: /node_modules/,
// //include: [path.join(process.cwd(),"frontend")], // only bundle files in this directory
// use: {
// loader: "babel-loader", // cf. .babelrc.json in this folder and browser list in package.json
// options: {
// // plugins: productionMode ? [] : ["react-refresh/babel"],
// cacheCompression: false,
// cacheDirectory: true,
// presets: [
// "@babel/preset-env",
// ["@babel/preset-react", {"runtime": "automatic"}],
// "@babel/preset-typescript",
// ],
// plugins: [
// "@babel/plugin-transform-runtime",
// ["@babel/plugin-proposal-decorators",{
// decoratorsBeforeExport:true
// }]
// ],
// },
// },
// },
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader?' +
JSON.stringify({
configFile: configFile,
compilerOptions: {
declaration: !es5,
/*
for webpack we overwrite the module settings of the modules' tsconfig file
because we NEED esnext for code splitting. But the VM we currently use for the registry does not support esnext modules
*/
module: 'esnext',
moduleResolution: 'node',
},
...config.tsConfigOverwrites,
}),
},
],
},
{
test: /[\w]+/,
use: [
{
loader: path_1.default.resolve(__dirname, 'plugins', 'check-imports.js'),
options: {},
},
],
},
// {
// enforce: 'pre',
// test: /\.js$/,
// use: [
// {
// loader: 'source-map-loader',
// },
// ],
// },
];
if (es5 && config.internalsources && config.internalsources.length > 0) {
//usually a module that transpiles to es5 will only have es5 code in the bundle.
//however a module that INTERNALISES other dacore modules will directly include es6 code from @dacore/other_modules/lib
//which eventually results in an import of @dacore/core being bundled as 'const =', which trips up old browsers
//so we fix that here by just referring directly to the typescript source instead of the transpiled js for internalised modules
//however this means that for internalised modules THE SOURCE CODE NEEDS TO BE AVAILABLE. This is currently NOT the case with how we publish modules to yarn
//so that means internalised modules need to be LOCALLY AVAILABLE with yarn workspaces
plugins.push(new webpack_1.default.NormalModuleReplacementPlugin(/lincd\/lib\//, (resource) => {
let moduleName = resource.request.match(/lincd\/lib\//)[1];
if (config.internalsources.indexOf(moduleName) !== -1) {
console.log(colors.magenta('internal sources + ES5: Replacing /lib/ with /src/ for source-internalised module ' +
moduleName));
resource.request = resource.request.replace('/lib/', '/src/');
console.log(colors.magenta('internal sources + ES5: ' + resource.request));
console.log(colors.red("WARNING: Make sure you have the TYPESCRIPT SOURCE FILES of the modules listed as 'internal' AVAILABLE ON YOUR LOCAL MACHINE. So if you check in node_modules/your-internalised-module - that should be a symbolic link and you will find a 'src' folder with typescript files there."));
}
}));
}
return {
entry: config.entry
? config.entry
: tsConfig.files
? tsConfig.files
: './src/index.ts',
output: {
filename: (config.filename ? config.filename : cleanModuleName) +
(es5 ? '.es5' : '') +
'.js',
path: path_1.default.resolve(process.cwd(), config.bundlePath || 'dist'),
devtoolModuleFilenameTemplate: moduleName + '/[resource-path]',
},
devtool: productionMode ? 'source-map' : 'cheap-module-source-map',
// devtool: productionMode ? 'cheap-source-map' : 'cheap-source-map',
mode: productionMode ? 'production' : 'development',
//fixing a persistent but strange build error here that showed up once, this is a workaround. See: https://github.com/webpack-contrib/css-loader/issues/447
// node: {
// fs: 'empty',
// child_process: 'empty',
// },
resolve: {
extensions: ['.webpack.js', '.js', '.ts', '.tsx', '.json'],
alias: aliases,
// plugins: resolvePlugins,
fallback: { crypto: false },
},
resolveLoader: {
modules: [
path_1.default.join(__dirname, 'plugins'), //load webpack our own custom-made loaders from the plugin folder
path_1.default.join(__dirname, '..', 'node_modules'), //load webpack loaders from this lincd-cli library instead of the library that's using it to build its project
'node_modules',
],
},
optimization: {
minimize: productionMode,
minimizer: [
new terser_webpack_plugin_1.default({
extractComments: {
condition: /^\**!|@preserve|@license|@cc_on/i,
banner: (licenseFile) => {
return `License information can be found in ${licenseFile} and oss-licences.json`;
},
},
}),
],
},
watch: watch,
watchOptions: {
ignored: ['**/*.d.ts', '**/*.js.map', '**/*.scss.json'],
aggregateTimeout: 500,
},
module: {
rules,
},
//See plugins/externalise-modules.ts We're passing in a function here that determines what to exclude from the bundle and what not
//See also https://webpack.js.org/configuration/externals/
externals: (0, externalise_modules_1.default)(config, es5),
plugins: plugins,
stats: {
errorDetails: true, //config.debug,
chunks: false,
children: true,
version: true,
hash: false,
entrypoints: false,
modules: false,
},
//hide some info from output when in watch mode to keep it succinct
//stats:{chunks:!watch,version:!watch}//hide some info from output when in watch mode to keep it succinct
cache: {
// https://webpack.js.org/configuration/other-options/#cache
type: 'filesystem',
// cacheDirectory: path.resolve(process.cwd(),"node_modules",".cache","webpack"),
// name: "lincd-webpack-cache",
},
};
}
//# sourceMappingURL=config-webpack.js.map