UNPKG

@frontity/core

Version:

The core package of the Frontity framework.

164 lines (147 loc) 4.82 kB
import ignore from "./utils/ts-node-ignore"; import * as tsNode from "ts-node"; /** * This file gets transpiled to JS anyway, but if the users's * frontity.settings.(js|ts) is an ES Module, we cannot require an ES Module * from a commonjs module. * * This is why we use ts-node here as well as in the `dev` script. * It's only because we want the user to be able to use ES Modules syntax in * the frontity.settings.(js|ts) file like this. * * @example * ```js * export default { * name: 'my-theme', * state: {}, * packages: {}, * } * ``` */ tsNode.register({ transpileOnly: true, ignore, compilerOptions: { // Target latest version of ECMAScript. target: "es2017", // Search under node_modules for non-relative imports. moduleResolution: "node", // commonjs modules. module: "commonjs", // Allow default imports from modules with no default export. allowSyntheticDefaultImports: true, // Don't emit; allow Babel to transform files. noEmit: true, // Import non-ES modules as default imports. esModuleInterop: true, // Resolve JSON files. resolveJsonModule: true, // Support for JSX runtime. jsx: "react-jsx", // Support for emotion css prop with types jsxImportSource: "@emotion/react", // Transpile JS as well. allowJs: true, }, }); import "./utils/envs"; import { join } from "path"; import { remove } from "fs-extra"; import { getAllSites } from "@frontity/file-settings"; import generateEntryPoints from "./utils/entry-points"; import getConfig from "../config"; import getFrontity from "../config/frontity"; import { Mode } from "@frontity/types/config"; import cleanBuildFolders from "./utils/clean-build-folders"; import { webpackAsync } from "./utils/webpack"; import { readConfigurationsFromConfigFiles } from "./utils/read-configuration"; /** * The options of the build command. */ export interface BuildOptions { /** * The Webpack mode used, either "development" or "production". * * @defaultValue "production" */ mode: Mode; /** * The JavaScript transpilation target. Either "es5" or "module". * * @defaultValue "both" */ target: "es5" | "module" | "both"; /** * The publicPath used in Webpack. * * @defaultValue "/static/" */ publicPath: string; /** * Indicate if the Bundle Analyzer plugin should be included in the Webpack * configuration, in order to generate HTML files for bundle analyzing. * * @defaultValue false */ analyze?: boolean; } /** * The Frontity build command that creates all the bundles and assets necessary * to run the Frontity server. * * @param options - Defined in {@link BuildOptions}. * * @returns A promise that resolves when the build has finished. */ export default async ({ mode = "production", target = "both", publicPath = "/static/", analyze = false, }: BuildOptions): Promise<void> => { console.log(); console.log(` - mode: ${mode}`); console.log(` - target: ${target}`); console.log(` - public-path: ${publicPath}`); console.log(); // Setting up the env variable to consume in initial state. process.env.FRONTITY_INTERNAL_PUBLIC_PATH = publicPath || "/static"; // Get config from frontity.config.js files. const frontityConfig = getFrontity(); const { outDir } = frontityConfig; // Create the directories if they don't exist. Clean them if they do. await cleanBuildFolders({ outDir }); // Get all sites configured in frontity.settings.js with their packages. const sites = await getAllSites(); // Generate the bundles. One for the server, one for each client site. const entryPoints = await generateEntryPoints({ sites, outDir, mode }); // Read the extra configurations from files. const extraConfigurations = await readConfigurationsFromConfigFiles(sites); // Get FrontityConfig for Webpack. const config = getConfig({ mode, entryPoints, analyze, extraConfigurations, }); // Build and wait until webpack finished the clients first. // We need to do this because the server bundle needs to import // the client chunks.x.json, which are created by the clients. // // If target is both or es5, build the es5 bundle. if (target !== "module") { console.log("Building es5 bundle"); await webpackAsync(config.webpack.es5); } // If target is both or module, build the module bundle. if (target !== "es5") { console.log("Building module bundle"); await webpackAsync(config.webpack.module); } console.log("Building server bundle"); await webpackAsync(config.webpack.server); console.log(); // Remove the bundling folder after the build in production because // it is not needed anymore. if (mode === "production") await remove(join(outDir, "bundling")); };