@isle/core
Version:
Isle core package
3 lines (2 loc) • 6.87 kB
JavaScript
;function _interopDefault(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var logger=_interopDefault(require("@isle/logger")),fs=_interopDefault(require("fs")),cleanWebpackPlugin=require("clean-webpack-plugin"),HtmlWebpackPlugin=_interopDefault(require("html-webpack-plugin")),CopyWebpackPlugin=_interopDefault(require("copy-webpack-plugin")),merge=_interopDefault(require("webpack-merge")),TerserPlugin=_interopDefault(require("terser-webpack-plugin")),path=_interopDefault(require("path")),mkdirp=_interopDefault(require("mkdirp")),webpack=_interopDefault(require("webpack")),WebpackDevServer=_interopDefault(require("webpack-dev-server")),reactSnap=require("react-snap");class Plugin{setupWebpack({config:e,mode:t,paths:r}){return e}setupPrerender({config:e,mode:t,paths:r}){return e}}function setupWebpackConfig({mode:e,paths:t,plugins:r}){return r.reduce((r,n)=>n.setupWebpack({config:r,paths:t,mode:e}),{})}function setupPrerenderConfig({mode:e,paths:t,plugins:r}){return r.reduce((r,n)=>n.setupPrerender({config:r,paths:t,mode:e}),{})}function createTerserPluginInstance({isProduction:e}){return e?new TerserPlugin({terserOptions:{parse:{ecma:8},compress:{ecma:5,warnings:!1,comparisons:!1,inline:2},mangle:{safari10:!0},output:{ecma:5,comments:!1,ascii_only:!0}},parallel:!0,cache:!0,sourceMap:!0}):null}function createOptimizationConfig({isProduction:e}){return{minimize:e,minimizer:[createTerserPluginInstance({isProduction:e})].filter(Boolean),splitChunks:{chunks:"all"},runtimeChunk:!0}}function createModuleRules({isProduction:e}){return[{test:/\.jsx?$/,exclude:/node_modules/,use:["thread-loader",{loader:"babel-loader",options:{presets:["@isle/babel-preset"],cacheDirectory:!0,cacheCompression:e}}]}]}function createDevServerConfig({isProduction:e,contentBase:t,publicPath:r}){return e?{}:{contentBase:t,watchContentBase:!0,historyApiFallback:!0,hot:!0,publicPath:r,quiet:!0,clientLogLevel:"none"}}function getUserWebpackConfig({paths:e}){const t=e.webpackConfig;if(fs.existsSync(t))return require(t)}class DefaultWebpackPlugin extends Plugin{setupWebpack({mode:e,paths:t}){const r="production"===e,n={mode:e,entry:t.appEntry,output:{path:r?t.appBuild:void 0,filename:r?"[name].[chunkhash:8].js":"[name].js",chunkFilename:r?"[name].[chunkhash:8].chunk.js":"[name].chunk.js",publicPath:t.publicPath},optimization:createOptimizationConfig({isProduction:r}),devtool:r?"hidden-source-map":"eval-source-map",module:{rules:createModuleRules({isProduction:r})},plugins:[new cleanWebpackPlugin.CleanWebpackPlugin,new HtmlWebpackPlugin({template:t.appHtmlTemplate})],devServer:createDevServerConfig({isProduction:r,contentBase:t.appStatic,publicPath:t.publicPath})};r&&n.plugins.push(new CopyWebpackPlugin([{from:t.appStatic,to:t.appBuild}]));const o=getUserWebpackConfig({paths:t});return o?(logger.info(`Found webpack config in ${t.webpackConfig}, merging with defaults...`),merge(n,o)):n}}function loadTemplateDir(){try{const e=require.resolve("@isle/template/package.json"),t=path.dirname(e);return path.join(t,"src")}catch(e){logger.fatal('Isle could not find the @isle/template module. Try installing it with "npm i --save-dev @isle/template"')}}const templateDir=loadTemplateDir();function resolveFromTemplate(e){const t=e.replace(/\.\./g,"");return path.resolve(templateDir,t)}function copyFromTemplate(e,t){const r=resolveFromTemplate(e);try{fs.copyFileSync(r,t)}catch(r){throw logger.error(`Isle could not copy the ${e} template file to ${t}`),r}}const appDirectory=fs.realpathSync(process.cwd()),resolveApp=e=>path.resolve(appDirectory,e),defaultPaths={appRoot:resolveApp(""),appBuild:resolveApp("dist"),appStatic:resolveApp("static"),appEntry:resolveApp("src/index.js"),appComponent:resolveApp("src/App.js"),appHtmlTemplate:resolveApp("src/template.html"),webpackConfig:resolveApp("webpack.config.js"),publicPath:"/"},isleConfigPath=resolveApp("isle.config.js");function checkDirectoryExists(e,t){return fs.existsSync(e)?!!fs.lstatSync(e).isDirectory()||(logger.error(`The ${e} path is not a directory. Perhaps you created a file instead?`),!1):t?(mkdirp.sync(e),!0):(logger.error(`Isle could not find the ${e} directory`),!1)}function checkFileExists(e,t){if(!fs.existsSync(e)){if(t){const t=path.relative(appDirectory,e);return checkDirectoryExists(path.dirname(t),!0),copyFromTemplate(t,e),!0}return logger.error(`Isle could not find the ${e} file`),!1}return!!fs.lstatSync(e).isFile()||(logger.error(`The ${e} path is not a file. Perhaps you created a directory instead?`),!1)}function validatePaths(e={}){const t=Object.assign(defaultPaths,e);return[checkDirectoryExists(t.appStatic,!0),checkFileExists(t.appEntry,!0),checkFileExists(t.appHtmlTemplate,!0)].some(e=>!e)&&logger.fatal("Some files/directories are missing"),t}function validateConfig(e,t){"object"!=typeof e&&logger.fatal(`The config from ${t} is not an object (got ${typeof e} instead)`)}function getIsleConfig(e){validateConfig(e,"params");let t={};fs.existsSync(isleConfigPath)&&validateConfig(t=require(isleConfigPath),isleConfigPath);const r=Object.assign({},t,e);return r.plugins||(r.plugins=[]),r.plugins.unshift(new DefaultWebpackPlugin),r}const defaultPort=4444,createCompiler=e=>webpack(e);function onCompile(e,t){if(e)return logger.error(e),void(e.details&&logger.error(e.details));const r=t.toString({all:!1,warnings:!0,errors:!0});t.hasErrors()?logger.error(r):t.hasWarnings()?logger.warn(r):logger.info("Compiled succesfully!")}const runBuild=e=>new Promise((t,r)=>{createCompiler(e).run((e,n)=>{if(onCompile(e,n),e)return r(e);t()})});function runWatch(e){createCompiler(e).watch({},onCompile)}const getListenPort=e=>process.env.ISLE_DEV_PORT?parseInt(process.env.ISLE_DEV_PORT):e.devServer.port||4444;function runDevServer(e){const t=createCompiler(e);t.hooks.done.tap("done",e=>onCompile(null,e));const r=new WebpackDevServer(t,e.devServer),n=getListenPort(e);r.listen(n,"localhost",e=>{e&&logger.fatal(e),logger.info(`Listening on http://localhost:${n}/`)})}const defaultConfig={puppeteerArgs:["--no-sandbox"]};function runPrerender({config:e={},paths:t={}}){const r=Object.assign(defaultConfig,e);if(!r.source){const e=path.relative(t.appRoot,t.appBuild);r.source=e}reactSnap.run(r)}const fallbackMode="production"===process.env.NODE_ENV?"production":"development";async function isle(e={}){const{mode:t=fallbackMode,watch:r=!1,devServer:n=!1,paths:o={},plugins:i=[]}=getIsleConfig(e);logger.info(`Running in ${t} mode (watch=${r})`);const a=validatePaths(o),s=setupWebpackConfig({mode:t,paths:a,plugins:i});if(logger.info("Starting webpack compilation..."),n)return void runDevServer(s);if(r)return void runWatch(s);await runBuild(s);const p=setupPrerenderConfig({mode:t,paths:a,plugins:i});logger.info("Pre-rendering pages..."),runPrerender({config:p,paths:a})}isle.Plugin=Plugin,module.exports=isle;
//# sourceMappingURL=index.js.map