Work is often repeated to write some methods, organized and hosted to In GitHub Warehouse ,
Build an npm package, each time used, download and package into a file on demand, easy to use;
<!--more-->
Project address
NPM address: https://www.npmjs.com/package/wxh-tools;
GITHUB: https://github.com/Wxh16144/wxh-tools;
Tool screenshots:
Project catalogue
-
bin
- Www <span style= "font-size:.8em; color: green">//execute package commands
-
config
- Methods_list.json <span style= "font-size:.8em; color: green">//all/src/tools/list of methods below, created by create_methods_list.js
- webpack.config.js <span style= "font-size:.8em; color: green">//web pack configuration used for packaging
- Dist <span style= "font-size:.8em; color: green">//packaged directory
- Reoisutiry < span style= "font-size:.8em; color: green">// temporary directory for storing resources downloaded from git to local
-
src
- Tools <span style= "font-size:.8em; color: green">// Store commonly used methods (all)
-
utils
- Create_file_by_user_select.js <span style= "font-size:.8em; color: green">// / Create folders according to the method selected by the user
- Get_json_file.js <span style= "font-size:.8em; color: green">// Read and serialize the contents of JSON file
- Read_dir_file.js < span style= "font-size:.8em; color: green">// read all files in a directory
- Webpack_build.js <span style= "font-size:.8em; color: green">// webpack configuration
- Get.js < span style = "font-size:.8em; color: green">// download files from git
- Index.js < span style= "font-size:.8em; color: green">// Get user selection config
- Main.js < span style= "font-size:.8em; color: green">// entry file
- .babelrc
- Create_methods_list.js <span style= "font-size:.8em; color: green">//read src/tools/all methods and generate files
Installation dependency
npm install @babel/cli@7.5.5 @babel/core@7.5.5 @babel/preset-env@7.5.5 babel-loader@8.0.0-beta.0 core-js@3.1.4 download@7.1.0 inquirer@6.5.0 ora@3.4.0 rimraf@2.6.3 shelljs@0.8.3 webpack@4.37.0 webpack-cli@3.3.6 --save
The enumerated npm statements are too long. In order to be lazy, I also use src/utils/get_json_file.js method.
Demo:
const method = require('./src/utils/get_json_file'); const json_file = method('./package.json'); const dep = json_file.dependencies; const res = Object.keys(dep).reduce((str, key) => { return `${str} ${key}@${(dep[key]).slice(1)}` }, '') console.log(res); // @babel/cli@7.5.5 @babel/core@7.5.5 @babel/preset-env@7.5.5 babel-loader@8.0.0-beta.0 core-js@3.1.4 download@7.1.0 inquirer@6.5.0 ora@3.4.0 rimraf@2.6.3 shelljs@0.8.3 webpack@4.37.0 webpack-cli@3.3.6
Tool Packaging
get_json_file.js
Read the json file and serialize it
const fs = require('fs'); /** *Read the *. JSON file and serialize it back * * @param {*} filepath File Address * @returns Document content */ module.exports = (filepath) => { if (!filepath) return ''; const _Json = fs.readFileSync(filepath); return JSON.parse(_Json); };
read_dir_file.js
Read all files in a directory (excluding folders, no recursion)
const path = require('path'); const path_join = path.join; const fs = require('fs'); /** *Get all files in the directory (excluding folders) * * @param {*} [dir=path_join(__dirname)] Catalog * @param {*} [reg=/./] Regular expression of death * @returns File array */ module.exports = (dir = path_join(__dirname), reg = /./) => { // Read all files let files = fs.readdirSync(dir); return files.reduce((arr, item) => { // Get the file path let fPath = path_join(dir, item); // read let stat = fs.statSync(fPath); // Determine whether it is a document or not let isFile = stat.isFile(); // Filtering Regular Expression Conditions return isFile && reg.test(item) ? [...arr, item] : arr }, []); };
get.js
Download files from remote github repositories
download file packages; download npm address;
const path = require('path'); const path_join = path.join; const fs = require('fs'); const download = require('download'); /** *Download files from remote github repositories * * @param {array} files file name * @param {string} [savePath=path_join(__dirname, '../repository')] File Download and Save Address * @returns Promise */ module.exports = (files, savePath = path_join(__dirname, '../repository')) => { const URL = 'https://raw.githubusercontent.com/Wxh16144/wxh-tools/master/'; return Promise.all((Array.isArray(files) ? files : []) .map(file_name => download(URL + file_name, savePath))); };
The tool is ready to complete and start building CONFIG (index.js)
Use the inquirer console interaction package; inquirer npm address;
Load animation packages using ora; ora npm address;
Introduce required modules
// Path Processing const path = require('path'); const path_join = path.join; // Communication through console const inquirer = require('inquirer'); const prompt = inquirer.createPromptModule(); // Load animation const ora = require('ora'); // Get the download file const download_methods_list = require('./get');
Console interaction, a Promise array;
// Ask for additional methods const Ask_the_task = [ // Ask users what methods they need to use async () => { // Add animation const spinner = ora('Getting a list of all methods...').start(); // Download a list of all methods const res = await download_methods_list(['config/methods_list.json']); // Reading method list const methods_list = require('./utils/get_json_file')(path_join(__dirname, '../repository/methods_list.json')); // Stop animation spinner.stop(); const ALL_TOOLS_SERVER = (methods_list.methods_list || []).map(filename => { return filename.replace(/\.js$/, ''); }); // Create problems return prompt({ type: 'checkbox', name: 'tools_key', message: 'Please choose the method you need.', default: [], choices: ALL_TOOLS_SERVER }) }, // Ask the user to save the name () => prompt({ type: 'input', name: 'save_file_name', message: 'Save File Name', default: 'utils.js', }), // Ask users if they need to pack () => prompt({ type: 'confirm', name: 'is_build', message: 'Need to use webpack Pack', default: true }), ];
Ask questions from top to bottom
CONFIG selected by users is merged to derive the execution method.
/** *Cyclic Questioning * * @returns User Configuration */ const task = async () => { const config = {}; for (const fn of Ask_the_task) { const P = fn(); const res = await P; Object.assign(config, res) } return config; }; // Derived Questioning Method module.exports = task;
Download the corresponding method (main.js) according to the user's choice
Use rimraf to delete file packages; rimraf npm address;
Loading module
const path = require('path'); const path_join = path.join; const fs = require('fs'); // Delete files const rimraf = require('rimraf'); // Get the download file const download_methods_list = require('./get'); // Load animation const ora = require('ora'); // Web pack packaging const webpack_build_function = require('./utils/webpack_build'); // Interaction issues const task = require('./index');
Ask the user, download the method locally, merge the method files, and pack with webpack
// All questions const task = require('./index'); (async function () { const CONFIG = await task(); // Getting User Configuration const { tools_key = [], is_build = true } = CONFIG; // Temporary catalogue const DIRECTORY = path_join(__dirname, '../temporary/'); rimraf.sync(DIRECTORY); // Add download animation const download_spinner = ora('Downloading the selected method data...').start(); // Collection according to the selected method // Download a list of all methods const load_select_methods = await download_methods_list( tools_key.map(key => `src/tools/${key}.js`), path_join(__dirname, '../temporary') ); // Download completed download_spinner.succeed('The required method is downloaded'); // Add Create File Animation const create_file_spinner = ora('Create and generate files...').start(); const create_file_by_user_select = require('./utils/create_file_by_user_select'); const create_file = await create_file_by_user_select(CONFIG); create_file_spinner.succeed('Create Completion'); // Add packaged animation const build_spinner = ora('Processing files...').start(); const build_res = await webpack_build_function(CONFIG); build_spinner.succeed(`Handling Success,address:${build_res}`); }());
Create a merge file (create_file_by_user_select.js)
The method of downloading github to local temporary directory;
Packed files will have a global set of methods called WT in Windows
const path = require('path'); const path_join = path.join; const fs = require('fs'); /** *Create merge files * * @param {*} CONFIG User input configuration */ module.exports = async CONFIG => { // Get the temporary directory path const DIRECTORY = path_join(__dirname, '../../temporary/'); const { tools_key = [] } = CONFIG; let javascript = ''; tools_key.forEach(fileN => { // Import method by method javascript += `import ${fileN} from './${fileN}.js'; ` }); const myexport = tools_key.map(String).join(','); // Bind to Windows // Derivative method javascript += ` window.WT = { ${myexport} }; export { ${myexport} };` // Write to temporary directory fs.writeFileSync(path_join(DIRECTORY, 'utils.js'), javascript); }
Packing with webpack (webpack_build.js)
Pass in the user CONFIG configuration; identify whether to package with @babel/preset-env by -- build;
Download file packages using shell; shell npm address;
Here's a method process.cwd() to get the directory of the user's execution methods; use this as a web pack package export;
Execute webpack packaging using the configuration config/webpack.config.js file
const path = require('path'); const path_join = path.join; const fs = require('fs'); const shell = require('shelljs'); /** *Check that the filename entered by the user is legitimate * * @param {*} filename file name * @returns file name */ const get_File_Name = filename => { if (/\.js$/.test(filename)) { return filename } else { return filename + '.js' } } /** *Packing files with webpack * * @param {*} CONFIG User Configuration * @returns Result */ module.exports = async CONFIG => { // configuration parameter const { tools_key = [], is_build = true, save_file_name } = CONFIG; // Get the webpack configuration address const CONFIG_PATH = path_join(__dirname, '../../config/'); // Packing Output Path Address//User Open Console Address const OUTPUT_PATH = path_join(process.cwd(), get_File_Name(save_file_name)); // Splicing webpack command line const CMD = `npx webpack ${is_build ? '--build' : ''} --output ${OUTPUT_PATH}`; // Returns asynchronous results (shells are synchronous) return new Promise((resovle, reject) => { shell.cd(CONFIG_PATH); const EXEC_RES = shell.exec(CMD); if (EXEC_RES.code === 0) { resovle(OUTPUT_PATH); //Return the successful address } else { reject(EXEC_RES); //fail } }); };
configuration file
.babellrc
{ "presets": [ [ "@babel/preset-env", { "targets": { "node": "10" }, "modules": "umd", "useBuiltIns": "usage", "corejs": 3, } ] ], "plugins": [], "ignore": [ "src/tools" ] }
config/webpack.config.js
const path = require('path'); // Determine whether there is a -- build identifier const IS_BUILD = (Array.isArray(process.argv) ?process.argv : []).includes('--build'); // babel const BABEL_BUILD = { test: /\.js$/, exclude: /(node_modules|bower_components)/,//Exclude node_module directory use: { loader: 'babel-loader', options: { presets: [ ["@babel/preset-env", { modules:false, useBuiltIns: "usage", corejs: 3, }] ], plugins: [], } } }; module.exports = { entry: path.resolve(__dirname, '../temporary/utils.js'), mode: 'production', output: { filename: 'utils.js', path: path.resolve(__dirname, '../temporary/dist') }, module: { rules: [ (IS_BUILD ? BABEL_BUILD : {}) // --build ] } };
bin/www
#! /usr/bin/env node require('../src/main.js');
Publish to NPM
First modify the package.json file and add the bin attribute
The global method name is: wxh
"bin": { "wxh": "./bin/www" },
Log in to your npm account
npm adduser
Push packages into npm warehouse
npm publish
Notes for pushing npm packages
- Check if your package has been renamed in the npm Library
- Each push package changes the version field of package.json
Write at the end
At this point, our entire package has been written, and we can use it just by installing it globally.
After routine maintenance, we just need to add one method to the src/tools directory.
Slowly write a method create_methods_list.js;
Methods According to the method files in the / src/tools directory, methods_list.json file was generated into the config directory.
const fs = require('fs'); const path = require('path'); const path_join = path.join; const read_dir_file = require('./src/utils/read_dir_file'); // read const fileArr = read_dir_file(path_join(__dirname, './src/tools')); fs.writeFileSync(path_join(__dirname, './config/methods_list.json'), JSON.stringify({ methods_list: fileArr }) );