UNPKG

feds-cli

Version:

CLI for Front-end Dev Stack

132 lines (117 loc) 4.14 kB
const webpack = require('webpack') const pathExtName = require('path').extname const pathResolve = require('path').resolve const md5 = require('md5') const fs = require('fs') const globSync = require('glob').sync const appRootPath = require('app-root-path').toString() const vendorDLLPaths = require('../config/vendorDLLPaths') const {createNotification} = require('../utils') // ----------------------------------------------------------------------------- // PRIVATES const importRegex = /(from '|require\(')([\w\-_]+)/g const {dllName, dllOutputDir, dllJsonPath, dependenciesHashFilePath} = vendorDLLPaths // We calculate a hash of the package.json's dependencies, which we can use // to determine if dependencies have changed since the last time we built // the vendor dll. const currentDependenciesHash = md5( JSON.stringify(require(pathResolve(appRootPath, 'package.json')).dependencies) ) function webpackConfigFactory (modules) { return { // We only use this for development, so lets always include source maps. devtool: 'inline-source-map', entry: { [dllName]: modules }, output: { path: dllOutputDir, filename: `${dllName}.js`, library: dllName }, plugins: [ new webpack.DllPlugin({ path: dllJsonPath, name: dllName }) ] } } function getJsFilesFromSrcDir (srcPath) { return globSync(`${pathResolve(appRootPath, 'src', srcPath)}/**/*.js`) } function buildVendorDLL () { return new Promise((resolve, reject) => { Promise.all([ Promise.resolve(getJsFilesFromSrcDir('client')), Promise.resolve(getJsFilesFromSrcDir('shared/universal')) ]) .then(([clientFiles, universalFiles]) => { const isJsFile = file => pathExtName(file) === '.js' const allJSFiles = [...clientFiles, ...universalFiles].filter(isJsFile) const modules = allJSFiles.reduce((acc, cur) => { const fileContents = fs.readFileSync(cur, 'utf8') let match = importRegex.exec(fileContents) while (match != null) { acc.add(match[2]) match = importRegex.exec(fileContents) } return acc }, new Set()) createNotification({ title: 'vendorDLL', level: 'info', message: 'Vendor DLL build complete. Check console for module list.' }) console.log([...modules]) const webpackConfig = webpackConfigFactory([...modules]) const vendorDLLCompiler = webpack(webpackConfig) vendorDLLCompiler.run((err) => { if (err) { reject(err) } // Update the dependency hash if (!fs.existsSync(dllOutputDir)) { fs.mkdirSync(dllOutputDir) } fs.writeFileSync(dependenciesHashFilePath, currentDependenciesHash) resolve() }) }) }) } // ----------------------------------------------------------------------------- // DEFAULT EXPORT function ensureVendorDLLExists () { return new Promise((resolve, reject) => { if (!fs.existsSync(dependenciesHashFilePath)) { // builddll createNotification({ title: 'vendorDLL', level: 'warn', message: 'Generating a new vendor dll for boosted development performance...' }) buildVendorDLL().then(resolve).catch(reject) } else { // first check if the md5 hashes match const dependenciesHash = fs.readFileSync(dependenciesHashFilePath, 'utf8') const dependenciesChanged = dependenciesHash !== currentDependenciesHash if (dependenciesChanged) { createNotification({ title: 'vendorDLL', level: 'warn', message: 'New vendor dependencies detected. Regenerating the vendor dll...' }) buildVendorDLL().then(resolve).catch(reject) } else { createNotification({ title: 'vendorDLL', level: 'info', message: 'No changes to existing vendor dependencies. Using the existing vendor dll.' }) resolve() } } }) } module.exports = ensureVendorDLLExists