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

"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;