You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
9.6 KiB
174 lines
9.6 KiB
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const colorette_1 = require("colorette");
|
|
const webpack_cli_1 = require("webpack-cli");
|
|
const log_symbols_1 = __importDefault(require("log-symbols"));
|
|
const path_1 = __importDefault(require("path"));
|
|
const scaffold_utils_1 = require("./utils/scaffold-utils");
|
|
const utils_1 = require("./utils");
|
|
const types_1 = require("./types");
|
|
const { logger, getPackageManager } = webpack_cli_1.utils;
|
|
/**
|
|
*
|
|
* Generator for initializing a webpack config
|
|
*
|
|
* @class InitGenerator
|
|
* @extends CustomGenerator
|
|
* @returns {Void} After execution, transforms are triggered
|
|
*
|
|
*/
|
|
class InitGenerator extends types_1.CustomGenerator {
|
|
constructor(args, opts) {
|
|
super(args, opts);
|
|
this.autoGenerateConfig = opts.autoSetDefaults;
|
|
this.generationPath = opts.generationPath;
|
|
this.dependencies = ['webpack', 'webpack-cli', 'babel-plugin-syntax-dynamic-import'];
|
|
this.configuration = {
|
|
config: {
|
|
configName: 'config',
|
|
topScope: [],
|
|
webpackOptions: {
|
|
mode: "'production'",
|
|
entry: undefined,
|
|
output: undefined,
|
|
plugins: [],
|
|
module: {
|
|
rules: [],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
this.entryOption = './src/index.js';
|
|
this.configuration.config.topScope.push("const path = require('path');", "const webpack = require('webpack');", '\n');
|
|
this.configuration.config.webpackOptions.plugins.push('new webpack.ProgressPlugin()');
|
|
}
|
|
async prompting() {
|
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
const self = this;
|
|
logger.log(`${log_symbols_1.default.info}${colorette_1.blue(' INFO ')} ` +
|
|
'For more information and a detailed description of each question, have a look at: ' +
|
|
`${colorette_1.bold(colorette_1.green('https://github.com/webpack/webpack-cli/blob/master/INIT.md'))}`);
|
|
logger.log(`${log_symbols_1.default.info}${colorette_1.blue(' INFO ')} ` + 'Alternatively, run "webpack(-cli) --help" for usage info\n');
|
|
const { multiEntries } = await scaffold_utils_1.Confirm(self, 'multiEntries', 'Will your application have multiple bundles?', false, this.autoGenerateConfig);
|
|
const entryOption = await utils_1.entryQuestions(self, multiEntries, this.autoGenerateConfig);
|
|
if (typeof entryOption === 'string') {
|
|
// single entry apply when default is not used
|
|
if (entryOption.length > 0 && entryOption !== "'./src/index.js'") {
|
|
this.configuration.config.webpackOptions.entry = entryOption;
|
|
}
|
|
}
|
|
else if (typeof entryOption === 'object') {
|
|
// multiple entries
|
|
this.configuration.config.webpackOptions.entry = entryOption;
|
|
}
|
|
this.entryOption = entryOption;
|
|
const { outputDir } = await scaffold_utils_1.Input(self, 'outputDir', 'In which folder do you want to store your generated bundles?', 'dist', this.autoGenerateConfig);
|
|
// only apply when output dir is not default
|
|
if (outputDir !== 'dist') {
|
|
this.configuration.config.webpackOptions.output = {
|
|
path: `path.resolve(__dirname, '${outputDir}')`,
|
|
};
|
|
}
|
|
const { langType } = await scaffold_utils_1.List(self, 'langType', 'Will you use one of the below JS solutions?', ['No', utils_1.LangType.ES6, utils_1.LangType.Typescript], 'No', this.autoGenerateConfig);
|
|
utils_1.langQuestionHandler(this, langType);
|
|
this.langType = langType;
|
|
const { stylingType } = await scaffold_utils_1.List(self, 'stylingType', 'Will you use one of the below CSS solutions?', ['No', utils_1.StylingType.CSS, utils_1.StylingType.SASS, utils_1.StylingType.LESS, utils_1.StylingType.PostCSS], 'No', this.autoGenerateConfig);
|
|
const { ExtractUseProps, regExpForStyles } = utils_1.styleQuestionHandler(self, stylingType);
|
|
if (regExpForStyles) {
|
|
// Ask if the user wants to use extractPlugin
|
|
const { useExtractPlugin } = await scaffold_utils_1.Confirm(self, 'useExtractPlugin', 'Will you bundle your CSS files with MiniCssExtractPlugin?', false, this.autoGenerateConfig);
|
|
if (useExtractPlugin) {
|
|
const { cssBundleName } = await scaffold_utils_1.Input(self, 'cssBundleName', 'What will you name the CSS bundle?', 'main', this.autoGenerateConfig);
|
|
this.dependencies.push('mini-css-extract-plugin');
|
|
this.configuration.config.topScope.push(utils_1.tooltip.cssPlugin(), "const MiniCssExtractPlugin = require('mini-css-extract-plugin');", '\n');
|
|
if (cssBundleName.length !== 0) {
|
|
this.configuration.config.webpackOptions.plugins.push(`new MiniCssExtractPlugin({ filename:'${cssBundleName}.[contenthash].css' })`);
|
|
}
|
|
else {
|
|
this.configuration.config.webpackOptions.plugins.push("new MiniCssExtractPlugin({ filename:'style.css' })");
|
|
}
|
|
// Remove style-loader from the loader chain
|
|
ExtractUseProps.shift();
|
|
ExtractUseProps.unshift({
|
|
loader: 'MiniCssExtractPlugin.loader',
|
|
});
|
|
}
|
|
// load CSS assets, with or without mini-css-extract-plugin
|
|
this.configuration.config.webpackOptions.module.rules.push({
|
|
test: regExpForStyles,
|
|
use: ExtractUseProps,
|
|
});
|
|
}
|
|
// webpack Dev Server
|
|
const { useDevServer } = await scaffold_utils_1.Confirm(self, 'useDevServer', 'Do you want to use webpack-dev-server?', true, this.autoGenerateConfig);
|
|
if (useDevServer) {
|
|
this.dependencies.push('webpack-dev-server');
|
|
this.configuration.config.webpackOptions.devServer = {
|
|
open: true,
|
|
host: "'localhost'",
|
|
};
|
|
}
|
|
const { useHTMLPlugin } = await scaffold_utils_1.Confirm(self, 'useHTMLPlugin', 'Do you want to simplify the creation of HTML files for your bundle?', false, this.autoGenerateConfig);
|
|
if (useHTMLPlugin) {
|
|
// Html webpack Plugin
|
|
this.dependencies.push('html-webpack-plugin');
|
|
const htmlWebpackDependency = 'html-webpack-plugin';
|
|
this.configuration.config.topScope.push(`const HtmlWebpackPlugin = require('${htmlWebpackDependency}')`, '\n', utils_1.tooltip.html());
|
|
this.configuration.config.webpackOptions.plugins.push(`new HtmlWebpackPlugin({
|
|
template: 'index.html'
|
|
})`);
|
|
}
|
|
const { useWorkboxPlugin } = await scaffold_utils_1.Confirm(self, 'useWorkboxPlugin', 'Do you want to add PWA support?', true, this.autoGenerateConfig);
|
|
// webpack Dev Server
|
|
if (useWorkboxPlugin) {
|
|
this.configuration.config.topScope.push("const WorkboxWebpackPlugin = require('workbox-webpack-plugin');", '\n');
|
|
this.dependencies.push('workbox-webpack-plugin');
|
|
this.configuration.config.webpackOptions.plugins.push(`new WorkboxWebpackPlugin.GenerateSW({
|
|
swDest: 'sw.js',
|
|
clientsClaim: true,
|
|
skipWaiting: false,
|
|
})`);
|
|
}
|
|
this.configuration.config.webpackOptions.mode = this.autoGenerateConfig ? "'production'" : "'development'";
|
|
}
|
|
installPlugins() {
|
|
const packager = getPackageManager();
|
|
const opts = packager === 'yarn' ? { dev: true } : { 'save-dev': true };
|
|
this.scheduleInstallTask(packager, this.dependencies, opts, { cwd: this.generationPath });
|
|
}
|
|
writing() {
|
|
this.config.set('configuration', this.configuration);
|
|
const packageJsonTemplatePath = '../init-template/package.json.js';
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
this.fs.extendJSON(this.destinationPath('package.json'), require(packageJsonTemplatePath)(this.autoGenerateConfig));
|
|
const generateEntryFile = (entryPath, name) => {
|
|
entryPath = entryPath.replace(/'/g, '');
|
|
this.fs.copyTpl(path_1.default.resolve(__dirname, '../init-template/index.js'), this.destinationPath(entryPath), { name });
|
|
};
|
|
// Generate entry file/files
|
|
const entry = this.configuration.config.webpackOptions.entry || './src/index.js';
|
|
if (typeof entry === 'string') {
|
|
generateEntryFile(entry, 'your main file!');
|
|
}
|
|
else if (typeof entry === 'object') {
|
|
Object.keys(entry).forEach((name) => generateEntryFile(entry[name], `${name} main file!`));
|
|
}
|
|
// Generate README
|
|
this.fs.copyTpl(path_1.default.resolve(__dirname, '../init-template/README.md'), this.destinationPath('README.md'), {});
|
|
// Generate HTML template file
|
|
this.fs.copyTpl(path_1.default.resolve(__dirname, '../init-template/template.html'), this.destinationPath('index.html'), {});
|
|
if (this.langType === utils_1.LangType.ES6) {
|
|
this.fs.copyTpl(path_1.default.resolve(__dirname, '../init-template/.babelrc'), this.destinationPath('.babelrc'), {});
|
|
}
|
|
else if (this.langType === utils_1.LangType.Typescript) {
|
|
// Generate tsconfig
|
|
const tsConfigTemplatePath = '../init-template/tsconfig.json.js';
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
this.fs.extendJSON(this.destinationPath('tsconfig.json'), require(tsConfigTemplatePath));
|
|
}
|
|
}
|
|
}
|
|
exports.default = InitGenerator;
|
|
|