Last active
February 24, 2020 09:16
-
-
Save Cheny-chen/a35e3d50b898513a0230fa8e19e8ed40 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Author: ChenyChen, JCloudYu | |
| * Create: 2020/01/29 | |
| **/ | |
| const os = require('os'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const readline = require('readline'); | |
| (async()=>{ | |
| 'use strict'; | |
| if( process.argv.length < 3 ){ | |
| return console.error('** Missing Directory and Destination Filename!'); | |
| } | |
| const named_map = {}, unnamed_pool = []; | |
| const arrayFiles = await ReadMainFolder(process.argv[2]); | |
| for( const file of arrayFiles ){ | |
| ParseFile(file, named_map, unnamed_pool); | |
| } | |
| const output_map = [ | |
| { template:"./tmpl1.js", output:"./output.js" } | |
| ]; | |
| const TemplateResolver = global.BuildTemplate = function(strings, ...dynamics) { | |
| if ( this instanceof TemplateResolver) { | |
| this.statics = strings; | |
| this.dynamics = dynamics; | |
| return; | |
| } | |
| return new TemplateResolver(strings, ...dynamics); | |
| }; | |
| for(const {template:_tmpl_name, output:_out_name} of output_map) { | |
| try { | |
| const out_file = path.resolve(__dirname, _out_name); | |
| const write_stream = fs.createWriteStream(out_file, {flags: 'w'}); | |
| const tmpl_name = path.resolve(__dirname, _tmpl_name); | |
| const tmpl = require(tmpl_name); | |
| if ( tmpl instanceof TemplateResolver ) { | |
| const {statics, dynamics} = tmpl; | |
| await WriteToStream(write_stream, statics[0]); | |
| for ( let i=1; i<statics.length; i++ ) { | |
| const dynamic_content = dynamics[i-1]; | |
| if ( typeof dynamic_content !== "string" ) { | |
| await WriteToStream(write_stream, ''+dynamic_content); | |
| await WriteToStream(write_stream, statics[i]); | |
| continue; | |
| } | |
| const important = dynamic_content[0]==='!'; | |
| const optional = dynamic_content[0]==='?'; | |
| const key = (important||optional) ? dynamic_content.substring(1) : dynamic_content; | |
| const code_segment = named_map[key]; | |
| if ( code_segment !== undefined ) { | |
| await WriteToStream(write_stream, code_segment); | |
| } | |
| else | |
| if ( important ) { | |
| throw new Error(`Missing required named block \`${key}\``); | |
| } | |
| else { | |
| if ( !optional ) { | |
| console.error(`Mismatched named block \`${key}\``); | |
| } | |
| await WriteToStream(write_stream, ''); | |
| } | |
| await WriteToStream(write_stream, statics[i]); | |
| } | |
| } | |
| for ( const code_segment of unnamed_pool ) { | |
| await WriteToStream(write_stream, code_segment); | |
| } | |
| await CloseStream(write_stream); | |
| } | |
| catch(e) { | |
| console.error(e); | |
| } | |
| } | |
| function WriteToStream(stream, data) { | |
| return new Promise((resolve, reject)=>{ | |
| const should_wait = stream.write(data, ()=>resolve(true)); | |
| if ( !should_wait ) { | |
| reject(false); | |
| } | |
| }); | |
| } | |
| function CloseStream(stream) { | |
| return new Promise((resolve, reject)=>stream.end(resolve)); | |
| } | |
| async function ReadMainFolder(folder, arrayFiles = [], arrayFolder = []){ | |
| fs.readdirSync(folder, {withFileTypes: true}).forEach(filename=>{ | |
| if( filename.isDirectory() && !/^\..*|test*/.test(filename.name) ){ | |
| arrayFolder.push(path.join(folder, filename.name)); | |
| } | |
| if( !filename.isDirectory() && filename.name.indexOf('.js') > 0 ){ | |
| arrayFiles.push(path.join(folder, filename.name)); | |
| } | |
| }); | |
| if( arrayFolder.length > 0 ){ | |
| const temp = await ReadMainFolder(arrayFolder[0], arrayFiles); | |
| arrayFiles.concat(temp); | |
| } | |
| console.log('** The List of Files'); | |
| console.log(arrayFiles); | |
| return arrayFiles | |
| } | |
| function ParseFile(filePath, named, unnamed){ | |
| const readInterface = readline.createInterface({ | |
| input: fs.createReadStream(filePath), | |
| }); | |
| readInterface.on('line', generateContain); | |
| let flag = false, splitByEqualsSign = [], temp_unamed = ''; | |
| function generateContain(line){ | |
| if( line.indexOf('//@export') > -1 ){ | |
| splitByEqualsSign = line.split('='); | |
| line = os.EOL; | |
| flag = true; | |
| } | |
| else if( line.indexOf('//@endexport') > -1 ){ | |
| line = line.replace('//@endexport', ''); | |
| flag = false; | |
| if(temp_unamed){ | |
| unnamed.push(temp_unamed); | |
| temp_unamed = ''; | |
| } | |
| } | |
| if( flag ){ | |
| line = line.trim() + os.EOL; | |
| if( splitByEqualsSign[1] && !named.hasOwnProperty(splitByEqualsSign[1]) ){ | |
| named[splitByEqualsSign[1]] = ''; | |
| } | |
| else if( splitByEqualsSign.length > 1 && splitByEqualsSign[1] ){ | |
| named[splitByEqualsSign[1]] += line; | |
| } | |
| else if( line != os.EOL ){ | |
| temp_unamed += line; | |
| } | |
| } | |
| } | |
| } | |
| })(); |
Author
node embedded-script-packer.js <folder name> <template filename> -d <destination filename>
打錯了喔!是
node embedded-script-packer.js <source folder path> <template file path> [-d <additional source folder path>] [-o <output file path>]
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
node embedded-script-packer.js <folder name> <template filename> -d <destination filename>