From 2bcc424710993fbc50d5d055a0786d65ab1d9bff Mon Sep 17 00:00:00 2001 From: Maledong Date: Wed, 20 Apr 2022 18:08:27 +0800 Subject: [PATCH] replace necessary async functions with async/await 1. Some functions like 'fs' or 'graceFulFs' has been supporting 'async/await' for a long time, so this is a refactor to improve the related codes. 2. 'sass.render' is deprecated, use awaitable 'sass.compileAsync' instead. --- build.js | 120 +++++++++++++++++++++++------------------------------- server.js | 31 +++++++------- 2 files changed, 65 insertions(+), 86 deletions(-) diff --git a/build.js b/build.js index bb7e6fa68937d..c3dec7fc4c0d9 100755 --- a/build.js +++ b/build.js @@ -6,6 +6,7 @@ const fs = require('fs'); const gracefulFs = require('graceful-fs'); + // This is needed at least on Windows to prevent the `EMFILE: too many open files` error // https://github.com/isaacs/node-graceful-fs#global-patching gracefulFs.gracefulify(fs); @@ -268,7 +269,7 @@ function withPreserveLocale(preserveLocale) { } // This function builds the static/css folder for all the Sass files. -function buildCSS() { +async function buildCSS() { console.log('[sass] static/css started'); const labelForBuild = '[sass] static/css finished'; console.time(labelForBuild); @@ -277,88 +278,70 @@ function buildCSS() { const dest = path.join(__dirname, 'build/static/css/styles.css'); const sassOpts = { - file: src, - outFile: dest, outputStyle: process.env.NODE_ENV !== 'development' ? 'compressed' : 'expanded' }; - gracefulFs.mkdir( - path.join(__dirname, 'build/static/css'), - { recursive: true }, - (err) => { - if (err) { - throw err; - } - - sass.render(sassOpts, (error, result) => { - if (error) { - throw error; - } + const graceFulFsPromise = gracefulFs.promises; - postcss([autoprefixer]) - .process(result.css, { from: src }) - .then((res) => { - res.warnings().forEach((warn) => { - console.warn(warn.toString()); - }); + await graceFulFsPromise.mkdir(path.join(__dirname, 'build/static/css'), { + recursive: true + }); - gracefulFs.writeFile(dest, res.css, (err) => { - if (err) { - throw err; - } + const result = await sass.compileAsync(src, sassOpts); - console.timeEnd(labelForBuild); - }); - }); + postcss([autoprefixer]) + .process(result.css, { from: src }) + .then(async (res) => { + res.warnings().forEach((warn) => { + console.warn(warn.toString()); }); - } - ); + + await graceFulFsPromise.writeFile(dest, res.css); + console.timeEnd(labelForBuild); + }); } // This function copies the rest of the static assets to their subfolder in the // build directory. -function copyStatic() { +async function copyStatic() { console.log('[ncp] build/static started'); const labelForBuild = '[ncp] build/static finished'; console.time(labelForBuild); - gracefulFs.mkdir( + + const graceFulFsPromise = gracefulFs.promises; + + await graceFulFsPromise.mkdir(path.join(__dirname, 'build/static'), { + recursive: true + }); + + ncp( + path.join(__dirname, 'static'), path.join(__dirname, 'build/static'), - { recursive: true }, - (err) => { - if (err) { - throw err; + (error) => { + if (error) { + return console.error(error); } ncp( - path.join(__dirname, 'static'), - path.join(__dirname, 'build/static'), + path.join(__dirname, 'node_modules/jquery/dist/jquery.min.js'), + path.join(__dirname, 'build/static/js/jquery.min.js'), (error) => { if (error) { return console.error(error); } ncp( - path.join(__dirname, 'node_modules/jquery/dist/jquery.min.js'), - path.join(__dirname, 'build/static/js/jquery.min.js'), + path.join( + __dirname, + 'node_modules/jquery.fancytable/dist/fancyTable.min.js' + ), + path.join(__dirname, 'build/static/js/fancyTable.min.js'), (error) => { if (error) { return console.error(error); } - - ncp( - path.join( - __dirname, - 'node_modules/jquery.fancytable/dist/fancyTable.min.js' - ), - path.join(__dirname, 'build/static/js/fancyTable.min.js'), - (error) => { - if (error) { - return console.error(error); - } - console.timeEnd(labelForBuild); - } - ); + console.timeEnd(labelForBuild); } ); } @@ -398,25 +381,24 @@ function getSource(callback) { // name. It brings together all build steps and dependencies and executes them. function fullBuild(opts) { const { selectedLocales, preserveLocale } = opts; - getSource((err, source) => { + getSource(async (err, source) => { if (err) { throw err; } - // Executes the build cycle for every locale. - gracefulFs.readdir(path.join(__dirname, 'locale'), (e, locales) => { - if (e) { - throw e; - } - const filteredLocales = locales.filter( - (file) => - junk.not(file) && - (selectedLocales ? selectedLocales.includes(file) : true) - ); - const localesData = generateLocalesData(filteredLocales); - filteredLocales.forEach((locale) => { - buildLocale(source, locale, { preserveLocale, localesData }); - }); + const graceFulFsPromise = gracefulFs.promises; + const locales = await graceFulFsPromise.readdir( + path.join(__dirname, 'locale') + ); + + const filteredLocales = locales.filter( + (file) => + junk.not(file) && + (selectedLocales ? selectedLocales.includes(file) : true) + ); + const localesData = generateLocalesData(filteredLocales); + filteredLocales.forEach((locale) => { + buildLocale(source, locale, { preserveLocale, localesData }); }); }); } diff --git a/server.js b/server.js index bf1468ee067d1..d061d6fb28608 100644 --- a/server.js +++ b/server.js @@ -3,7 +3,7 @@ // The server where the site is exposed through a static file server // while developing locally. -const fs = require('fs'); +const fs = require('fs/promises'); const http = require('http'); const path = require('path'); const chokidar = require('chokidar'); @@ -48,21 +48,18 @@ function getLocale(filePath) { // This function has two meanings: // 1. Build for the specific language. // 2. Choose what languages for the menu. -function dynamicallyBuildOnLanguages(source, locale) { +async function dynamicallyBuildOnLanguages(source, locale) { + let localesData = null; + if (!selectedLocales || selectedLocales.length === 0) { - fs.readdir(path.join(__dirname, 'locale'), (err, locales) => { - if (err) { - throw err; - } - - const filteredLocales = locales.filter((file) => junk.not(file)); - const localesData = build.generateLocalesData(filteredLocales); - build.buildLocale(source, locale, { preserveLocale, localesData }); - }); + const localesPath = path.join(__dirname, 'locale'); + const locales = await fs.readdir(localesPath); + const filteredLocales = locales.filter((file) => junk.not(file)); + localesData = build.generateLocalesData(filteredLocales); } else { - const localesData = build.generateLocalesData(selectedLocales); - build.buildLocale(source, locale, { preserveLocale, localesData }); + localesData = build.generateLocalesData(selectedLocales); } + build.buildLocale(source, locale, { preserveLocale, localesData }); } build.getSource((err, source) => { @@ -70,23 +67,23 @@ build.getSource((err, source) => { throw err; } - locales.on('change', (filePath) => { + locales.on('change', async (filePath) => { const locale = getLocale(filePath); if (!selectedLocales || selectedLocales.includes(locale)) { console.log( `The language ${locale} is changed, '${filePath}' is modified.` ); - dynamicallyBuildOnLanguages(source, locale); + await dynamicallyBuildOnLanguages(source, locale); } }); - locales.on('add', (filePath) => { + locales.on('add', async (filePath) => { const locale = getLocale(filePath); if (!selectedLocales || selectedLocales.includes(locale)) { console.log(`The language ${locale} is changed, '${filePath}' is added.`); - dynamicallyBuildOnLanguages(source, locale); + await dynamicallyBuildOnLanguages(source, locale); locales.add(filePath); } });