From 222ccdc27f73b0ebe95b1781809ac126435f86ae Mon Sep 17 00:00:00 2001 From: dhruvdutt Date: Thu, 5 Jul 2018 19:00:35 +0530 Subject: [PATCH] feat(init): add typescript support --- .gitignore | 3 - package-lock.json | 6 +- packages/init/.gitignore | 1 + packages/init/.npmignore | 3 + packages/init/{index.js => index.ts} | 16 ++--- packages/init/init.js | 94 --------------------------- packages/init/init.ts | 97 ++++++++++++++++++++++++++++ packages/init/package-lock.json | 15 +++++ packages/init/package.json | 8 +++ packages/init/tsconfig.json | 3 + packages/init/types/Transform.ts | 15 +++++ packages/init/types/index.ts | 3 + 12 files changed, 155 insertions(+), 109 deletions(-) create mode 100644 packages/init/.gitignore create mode 100644 packages/init/.npmignore rename packages/init/{index.js => index.ts} (57%) delete mode 100644 packages/init/init.js create mode 100644 packages/init/init.ts create mode 100644 packages/init/tsconfig.json create mode 100644 packages/init/types/Transform.ts create mode 100644 packages/init/types/index.ts diff --git a/.gitignore b/.gitignore index 517a64896a2..b1d3a1b1ac0 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,3 @@ lerna-debug.log # Yarn lock file yarn.lock - -# Custom typings -custom_typing/*.js diff --git a/package-lock.json b/package-lock.json index 5ef86068775..ec22078cdcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14936,9 +14936,9 @@ "dev": true }, "please-upgrade-node": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.0.tgz", - "integrity": "sha512-pTKaalHdeccg+4FOxRsnZx+z/+n68WAY12RIKQh6eOdTnXu2LivwFTsJkAtQyiq3CSlbJ2Uw0R028Lz69kYgoA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz", + "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", "dev": true, "requires": { "semver-compare": "^1.0.0" diff --git a/packages/init/.gitignore b/packages/init/.gitignore new file mode 100644 index 00000000000..a6c7c2852d0 --- /dev/null +++ b/packages/init/.gitignore @@ -0,0 +1 @@ +*.js diff --git a/packages/init/.npmignore b/packages/init/.npmignore new file mode 100644 index 00000000000..668500d4c4a --- /dev/null +++ b/packages/init/.npmignore @@ -0,0 +1,3 @@ +types +tsconfig.json +*.ts diff --git a/packages/init/index.js b/packages/init/index.ts similarity index 57% rename from packages/init/index.js rename to packages/init/index.ts index c2efb718eb3..46a1dace60c 100644 --- a/packages/init/index.js +++ b/packages/init/index.ts @@ -1,25 +1,23 @@ -"use strict"; - -const npmPackagesExists = require("@webpack-cli/utils/npm-packages-exists"); -const defaultGenerator = require("@webpack-cli/generators/init-generator"); -const modifyConfigHelper = require("@webpack-cli/utils/modify-config-helper"); +import * as defaultGenerator from "@webpack-cli/generators/init-generator"; +import * as modifyConfigHelper from "@webpack-cli/utils/modify-config-helper"; +import * as npmPackagesExists from "@webpack-cli/utils/npm-packages-exists"; /** * * First function to be called after running the init flag. This is a check, * if we are running the init command with no arguments or if we got dependencies * - * @param {Array} args - array of arguments such as + * @param {String[]} args - array of arguments such as * packages included when running the init command * @returns {Function} creator/npmPackagesExists - returns an installation of the package, * followed up with a yeoman instance of that if there's packages. If not, it creates a defaultGenerator */ -module.exports = function initializeInquirer(...args) { - const packages = args.slice(3); +export default function initializeInquirer(...args: string[]): Function { + const packages: string[] = args.slice(3); if (packages.length === 0) { return modifyConfigHelper("init", defaultGenerator); } return npmPackagesExists(packages); -}; +} diff --git a/packages/init/init.js b/packages/init/init.js deleted file mode 100644 index fdbb4db9d23..00000000000 --- a/packages/init/init.js +++ /dev/null @@ -1,94 +0,0 @@ -"use strict"; - -const path = require("path"); -const j = require("jscodeshift"); -const chalk = require("chalk"); -const pEachSeries = require("p-each-series"); - -const runPrettier = require("@webpack-cli/utils/run-prettier"); -const astTransform = require("@webpack-cli/utils/recursive-parser"); -const propTypes = require("@webpack-cli/utils/prop-types"); - -/** - * - * Maps back transforms that needs to be run using the configuration - * provided. - * - * @param {Object} transformObject - An Object with all transformations - * @param {Object} config - Configuration to transform - * @returns {Object} - An Object with the transformations to be run - */ - -function mapOptionsToTransform(config) { - return Object.keys(config.webpackOptions).filter(k => propTypes.has(k)); -} - -/** - * - * Runs the transformations from an object we get from yeoman - * - * @param {Object} webpackProperties - Configuration to transform - * @param {String} action - Action to be done on the given ast - * @returns {Promise} - A promise that writes each transform, runs prettier - * and writes the file - */ - -module.exports = function runTransform(webpackProperties, action) { - // webpackOptions.name sent to nameTransform if match - const webpackConfig = Object.keys(webpackProperties).filter(p => { - return p !== "configFile" && p !== "configPath"; - }); - const initActionNotDefined = action && action !== "init" ? true : false; - - webpackConfig.forEach(scaffoldPiece => { - const config = webpackProperties[scaffoldPiece]; - const transformations = mapOptionsToTransform(config); - const ast = j( - initActionNotDefined - ? webpackProperties.configFile - : "module.exports = {}" - ); - const transformAction = action || null; - - return pEachSeries(transformations, f => { - return astTransform(j, ast, config.webpackOptions[f], transformAction, f); - }) - .then(_ => { - let configurationName; - if (!config.configName) { - configurationName = "webpack.config.js"; - } else { - configurationName = "webpack." + config.configName + ".js"; - } - - const outputPath = initActionNotDefined - ? webpackProperties.configPath - : path.join(process.cwd(), configurationName); - const source = ast.toSource({ - quote: "single" - }); - - runPrettier(outputPath, source); - }) - .catch(err => { - console.error(err.message ? err.message : err); - }); - }); - if (initActionNotDefined && webpackProperties.config.item) { - process.stdout.write( - "\n" + - chalk.green( - `Congratulations! ${ - webpackProperties.config.item - } has been ${action}ed!\n` - ) - ); - } else { - process.stdout.write( - "\n" + - chalk.green( - "Congratulations! Your new webpack configuration file has been created!\n" - ) - ); - } -}; diff --git a/packages/init/init.ts b/packages/init/init.ts new file mode 100644 index 00000000000..9e721f94371 --- /dev/null +++ b/packages/init/init.ts @@ -0,0 +1,97 @@ +import chalk from "chalk"; +import * as j from "jscodeshift"; +import pEachSeries = require("p-each-series"); +import * as path from "path"; + +import * as propTypes from "@webpack-cli/utils/prop-types"; +import * as astTransform from "@webpack-cli/utils/recursive-parser"; +import * as runPrettier from "@webpack-cli/utils/run-prettier"; + +import { IError } from "./types"; +import { IConfiguration, IWebpackProperties } from "./types/Transform"; + +/** + * + * Maps back transforms that needs to be run using the configuration + * provided. + * + * @param {Object} transformObject - An Object with all transformations + * @param {Object} config - Configuration to transform + * @returns {Array} - An array with the transformations to be run + */ + +const mapOptionsToTransform = (config: IConfiguration): string[] => + Object.keys(config.webpackOptions) + .filter((key: string): boolean => propTypes.has(key)); + +/** + * + * Runs the transformations from an object we get from yeoman + * + * @param {Object} webpackProperties - Configuration to transform + * @param {String} action - Action to be done on the given ast + * @returns {Promise} - A promise that writes each transform, runs prettier + * and writes the file + */ + +export default function runTransform(webpackProperties: IWebpackProperties, action: string): void { + // webpackOptions.name sent to nameTransform if match + const webpackConfig: string[] = + Object + .keys(webpackProperties) + .filter((p: string): boolean => p !== "configFile" && p !== "configPath"); + + const initActionNotDefined: boolean = (action && action !== "init") || false; + + webpackConfig.forEach((scaffoldPiece: string): Promise => { + const config: IConfiguration = webpackProperties[scaffoldPiece]; + const transformations: string[] = mapOptionsToTransform(config); + const ast = j( + initActionNotDefined + ? webpackProperties.configFile + : "module.exports = {}", + ); + const transformAction: string | null = action || null; + + return pEachSeries(transformations, (f: string): Promise => { + return astTransform(j, ast, config.webpackOptions[f], transformAction, f); + }) + .then((_?: any) => { + let configurationName: string = "webpack.config.js"; + if (config.configName) { + configurationName = "webpack." + config.configName + ".js"; + } + + const outputPath: string = initActionNotDefined + ? webpackProperties.configPath + : path.join(process.cwd(), configurationName); + + const source: string = ast.toSource({ + quote: "single", + }); + + runPrettier(outputPath, source); + }) + .catch((err: IError) => { + console.error(err.message ? err.message : err); + }); + }); + + if (initActionNotDefined && webpackProperties.config.item) { + process.stdout.write( + "\n" + + chalk.green( + `Congratulations! ${ + webpackProperties.config.item + } has been ${action}ed!\n`, + ), + ); + } else { + process.stdout.write( + "\n" + + chalk.green( + "Congratulations! Your new webpack configuration file has been created!\n", + ), + ); + } +} diff --git a/packages/init/package-lock.json b/packages/init/package-lock.json index 9362ce138c9..98ea4e9ed36 100644 --- a/packages/init/package-lock.json +++ b/packages/init/package-lock.json @@ -2,6 +2,16 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@types/node": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.1.tgz", + "integrity": "sha512-AFLl1IALIuyt6oK4AYZsgWVJ/5rnyzQWud7IebaZWWV3YmgtPZkQmYio9R5Ze/2pdd7XfqF5bP+hWS11mAKoOQ==" + }, + "@types/p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha512-bqQAn+tAs1QwGQYNIbv8a0XT8Pzl6Z+6SVpca+vJngcvwRwws7eJj9P2rTJDpjwOSyX1iRNSlIokUlusV0mP0A==" + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -1505,6 +1515,11 @@ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, + "typescript": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", + "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==" + }, "underscore": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", diff --git a/packages/init/package.json b/packages/init/package.json index 5e4a006f01d..b58c0d83f7b 100644 --- a/packages/init/package.json +++ b/packages/init/package.json @@ -14,5 +14,13 @@ "chalk": "^2.4.1", "jscodeshift": "^0.5.0", "p-each-series": "^1.0.0" + }, + "devDependencies": { + "@types/node": "^10.3.6", + "@types/p-each-series": "^1.0.0", + "typescript": "^2.9.2" + }, + "scripts": { + "build": "tsc" } } diff --git a/packages/init/tsconfig.json b/packages/init/tsconfig.json new file mode 100644 index 00000000000..4082f16a5d9 --- /dev/null +++ b/packages/init/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.json" +} diff --git a/packages/init/types/Transform.ts b/packages/init/types/Transform.ts new file mode 100644 index 00000000000..89622b85f62 --- /dev/null +++ b/packages/init/types/Transform.ts @@ -0,0 +1,15 @@ +export interface IWebpackProperties extends Object { + configFile: string; + configPath: string; + webpackOptions: IConfiguration; + config: { + item: string; + configName: string; + }; +} + +export interface IConfiguration extends Object { + configName: string; + webpackOptions: object; + topScope: string[]; +} diff --git a/packages/init/types/index.ts b/packages/init/types/index.ts new file mode 100644 index 00000000000..c0f13602567 --- /dev/null +++ b/packages/init/types/index.ts @@ -0,0 +1,3 @@ +export interface IError { + message?: string; +}