fusox
Version:
Command line wrapper for fuse-box
179 lines (156 loc) • 7.23 kB
JavaScript
const {parseBoolean, findExistingFile, getTransparentCorsSnippet, printHeader, getFreePort} = require('../helpers')
const path = require('path')
const util = require('util')
const {existsSync} = require('fs')
const fsb = require('fuse-box')
const {YAMLPlugin} = require('fuse-box-yaml')
module.exports = {parseBuildBrowserFlags, buildBrowserCommand}
function parseBuildBrowserFlags (args, flags) {
let customMainFile = args.main
let customIndexFile = args.index
let assetsDestinationPath = flags.destinationPath
let assetsWebPathResolver = (f) => f
let assetsMainPath = '.'
let openWebPage = args.open === undefined ? false : parseBoolean(args.open)
let runDevServer = flags.runApplication || openWebPage
let watchForChanges = args.watch === undefined ? runDevServer : parseBoolean(args.watch)
// let treeshakeCode = args.treeshake === undefined ? flags.mode === 'production' : parseBoolean(args.treeshake)
// let isolateBundleApi = args.isolate === undefined ? flags.mode === 'production' : parseBoolean(args.isolate)
// let extractCss = args['extract-css'] === undefined ? flags.mode === 'production' : parseBoolean(args['extract-css'])
let hashFileNames = args.hash === undefined ? flags.mode === 'production' : parseBoolean(args.hash)
let customMainFilePath = customMainFile && flags.resolveSourcePath(customMainFile)
let defaultMainFilePath = flags.resolveSourcePath('index.tsx')
let alternateMainFilePath = flags.resolveSourcePath('index.ts')
let mainFilePath = findExistingFile(customMainFilePath, defaultMainFilePath, alternateMainFilePath)
if (!mainFilePath || !existsSync(mainFilePath)) {
throw new Error(util.format(
'Could not find main file at "%s" or "%s" or "%s", see "--main" option',
flags.resolveSourcePathRelative(customMainFilePath),
flags.resolveSourcePathRelative(defaultMainFilePath),
flags.resolveSourcePathRelative(alternateMainFilePath)
))
}
let mainFile = mainFilePath && path.basename(mainFilePath)
let mainFilePathRelative = mainFilePath.replace(flags.sourcePath + '/', '')
let customIndexFilePath = customIndexFile && flags.resolveSourcePath(customIndexFile)
let defaultIndexFilePath = flags.resolveSourcePath('index.html')
let fallbackIndexFilePath = path.resolve(__dirname, '../assets/browser.html')
let indexFilePath = findExistingFile(customIndexFilePath, defaultIndexFilePath, fallbackIndexFilePath)
let indexFile = indexFilePath && path.basename(indexFilePath)
if (!indexFilePath || !existsSync(indexFilePath)) {
throw new Error('Could not find the index file, see "--index" option')
}
let appName = flags.appName || mainFile.replace(path.extname(mainFile), '')
return {
...flags,
mainFile,
mainFilePath,
mainFilePathRelative,
indexFile,
indexFilePath,
appName,
assetsDestinationPath,
assetsWebPathResolver,
assetsMainPath,
runDevServer,
openWebPage,
watchForChanges,
// treeshakeCode,
// isolateBundleApi,
// extractCss,
hashFileNames
}
}
function buildBrowserCommand (flags) {
return getFreePort(flags.defaultDevServerPort)
.then((devServerPort) => {
flags.devServerPort = devServerPort
if (flags.globalName) {
printHeader('Main package exported as window["%s"] in browser', flags.globalName)
}
let fuse = fsb.FuseBox.init({
target: 'browser',
homeDir: flags.sourcePath,
modulesFolder: flags.nodeModulesPath,
output: util.format('%s/$name.js', flags.destinationPath),
tsConfig: flags.tsconfigPath,
sourceMaps: flags.generateSourceMaps,
hash: flags.hashFileNames,
cache: flags.useCache,
log: true,
ensureTsConfig: false,
globals: flags.globalName ? {default: flags.globalName} : null,
plugins: [
YAMLPlugin(),
fsb.WebIndexPlugin({template: flags.indexFilePath}),
[fsb.StylusPlugin(), fsb.PostCSSPlugin(flags.postCssConfig), fsb.CSSResourcePlugin({
dist: flags.assetsDestinationPath,
resolve: flags.assetsWebPathResolver
}), fsb.CSSPlugin()],
[fsb.SassPlugin(), fsb.PostCSSPlugin(flags.postCssConfig), fsb.CSSResourcePlugin({
dist: flags.assetsDestinationPath,
resolve: flags.assetsWebPathResolver
}), fsb.CSSPlugin()],
[fsb.LESSPlugin(), fsb.PostCSSPlugin(flags.postCssConfig), fsb.CSSResourcePlugin({
dist: flags.assetsDestinationPath,
resolve: flags.assetsWebPathResolver
}), fsb.CSSPlugin()],
[fsb.PostCSSPlugin(flags.postCssConfig), fsb.CSSResourcePlugin({
dist: flags.assetsDestinationPath,
resolve: flags.assetsWebPathResolver
}), fsb.CSSPlugin()],
// fsb.EnvPlugin(flags.envConfig),
fsb.CopyPlugin({
useDefault: false,
files: flags.assetFilesExtensions,
dest: '.',
resolve: flags.assetsMainPath
}),
fsb.JSONPlugin(),
fsb.ReplacePlugin(flags.processEnvConfig),
flags.mode === 'production' && flags.uglifyCode && fsb.UglifyESPlugin(),
// flags.mode === 'production' && fsb.QuantumPlugin({
// target: 'browser',
// treeshake: flags.treeshakeCode,
// uglify: flags.uglifyCode,
// css: flags.extractCss,
// containedAPI: flags.isolateBundleApi,
// bakeApiIntoBundle: flags.appName,
// }),
]
})
let mainBundle
if (flags.mode === 'production') {
// bundle everything into a single file
mainBundle = fuse.bundle(flags.appName)
.instructions(util.format('> %s %s', flags.mainFilePathRelative, flags.dynamicFilesInstructions))
} else {
// todo: bundle splitting disabled until a fix is available https://github.com/fuse-box/fuse-box/issues/1119
// split vendors from sources for faster recompilation
// let vendorsBundle = fuse.bundle('vendors')
// .instructions(util.format('~ %s', flags.mainFilePathRelative))
// mainBundle = fuse.bundle(flags.appName)
// .instructions(util.format('!> [%s]', flags.mainFilePathRelative))
mainBundle = fuse.bundle(flags.appName)
.instructions(util.format('> %s %s', flags.mainFilePathRelative, flags.dynamicFilesInstructions))
}
if (flags.runCorsProxy) {
mainBundle.plugin(fsb.BannerPlugin(getTransparentCorsSnippet(
flags.envConfig.CORS_PROXY_HOST,
flags.envConfig.CORS_PROXY_PORT,
flags.envConfig.NODE_ENV
)))
}
if (flags.runDevServer) {
if (flags.defaultDevServerPort !== flags.devServerPort) {
printHeader('Dev server port "%s" already in use, fallback to "%s"', flags.defaultDevServerPort, flags.devServerPort)
}
fuse.dev({port: flags.devServerPort, open: flags.openWebPage})
}
if (flags.watchForChanges && flags.mode === 'development') {
mainBundle.watch().hmr({port: flags.devServerPort})
}
printHeader('Launching fuse-box for "browser"')
return fuse.run()
})
}