Skip to content

Commit

Permalink
fix saving archetype options
Browse files Browse the repository at this point in the history
  • Loading branch information
jchip committed Oct 3, 2020
1 parent 72aed78 commit a1ad08d
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 177 deletions.
99 changes: 15 additions & 84 deletions packages/xarc-app-dev/src/config/archetype.ts
Original file line number Diff line number Diff line change
@@ -1,98 +1,21 @@
/* eslint-disable @typescript-eslint/no-var-requires, max-statements, no-console */

import { XarcOptions } from "./opt2/xarc-options";

const Path = require("path");
const { merge } = require("lodash");
const { getMyPkg } = require("../lib/utils");
const constants = require("./constants");

import { getDevArchetypeLegacy } from "./options";
import { createGitIgnoreDir } from "../lib/utils";
const Fs = require("fs");
const _ = require("lodash");
const xenvConfig = require("xenv-config");
const makeAppMode = require("@xarc/app/lib/app-mode");
const { getDefaultArchetypeOptions } = require("./options");
const getEnvProxy = require("./env-proxy");
const Path = require("path");

let cachedArchetype = null;

function getDevArchetypeLegacy() {
const defaultArchetypeConfig = getDefaultArchetypeOptions();
const userConfig = defaultArchetypeConfig.options;

const webpack = require("./env-webpack")();
const babel = require("./env-babel")();
const karma = require("./env-karma")();

const { myPkg: devPkg, myDir: devDir } = getMyPkg();
const configDir = Path.join(devDir, "config");
const devRequire = require(Path.join(devDir, "require"));

const config = {
...defaultArchetypeConfig,
devDir,
devPkg,
devRequire,
webpack,
karma,
jest: Object.assign({}, userConfig.jest),
babel,
config: {
babel: `${configDir}/babel`,
eslint: `${configDir}/eslint`,
karma: `${configDir}/karma`,
mocha: `${configDir}/mocha`,
webpack: `${configDir}/webpack`,
jest: `${configDir}/jest`,
...userConfig.configPaths
},
prodDir: constants.PROD_DIR,
eTmpDir: constants.ETMP_DIR,
AppMode: makeAppMode(constants.PROD_DIR, userConfig.reactLib)
};

const topConfigSpec = {
devOpenBrowser: { env: "ELECTRODE_DEV_OPEN_BROWSER", default: false }
};

const typeScriptOption =
userConfig.typescript === false
? {
babel: { enableTypeScript: userConfig.typescript }
}
: {};

const archetypeConfig = Object.assign(
_.merge(config, typeScriptOption),
xenvConfig(topConfigSpec, _.pick(userConfig, Object.keys(topConfigSpec)), { merge })
);

archetypeConfig.babel.hasMultiTargets =
Object.keys(archetypeConfig.babel.envTargets)
.sort()
.join(",") !== "default,node";

let AppMode;

//
// AppMode could cause circular dependency loading
// Make it a get property so it's load after this file is processed
//
Object.defineProperty(archetypeConfig, "AppMode", {
get() {
if (!AppMode) {
AppMode = makeAppMode(archetypeConfig.prodDir, archetypeConfig.reactLib);
}

return AppMode;
}
});

return archetypeConfig;
function createElectrodeTmpDir(eTmpDir = ".etmp") {
createGitIgnoreDir(Path.resolve(eTmpDir), "Electrode tmp dir");
}

function saveArchetypeConfig(config) {
const filename = ".etmp/xarc-options.json";
const filename = `${config.eTmpDir}/xarc-options.json`;
const copy = { ...config, pkg: undefined, devPkg: undefined };
let existStr;

Expand All @@ -105,6 +28,8 @@ function saveArchetypeConfig(config) {
const str = JSON.stringify(copy, null, 2);
if (str !== existStr) {
try {
createElectrodeTmpDir(config.eTmpDir);

Fs.writeFileSync(filename, str);
} catch (err) {
console.error(
Expand All @@ -115,7 +40,13 @@ function saveArchetypeConfig(config) {
}
}

module.exports = function getDevArchetype(user: XarcOptions = {}) {
/**
* Get development options
*
* @param user - user options
* @returns options - final options with defaults and env applied
*/
module.exports = function getDevOptions(user: XarcOptions = {}) {
if (cachedArchetype) {
cachedArchetype._fromCache = true;
// maintained for backwards compatibility
Expand Down
20 changes: 16 additions & 4 deletions packages/xarc-app-dev/src/config/opt2/babel-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ export type BabelOptions = {
*
* - **Default: `false`**
* - if not set, then we check env `ENABLE_BABEL_FLOW`
* - To require the `@flow` directive in source, set it to `{ requireDirective: true }`
*
* requireDirective behavior (defaulted to **NOT** required):
*
* - When this plugin is enabled, it's defaulted to not require the `@flow` directive in source.
* - To change this behavior, set this option to `{ requireDirective: true }`
*/
enableFlow?: boolean | { requireDirective: boolean };

Expand All @@ -33,8 +37,12 @@ export type BabelOptions = {
/**
* Add `@babel/plugin-proposal-decorators`
* - **Default: `false`**
* - To use the legacy decorators behavior, set it to `{ legacy: true }`
* - if not set, then we check env `BABEL_PROPOSAL_DECORATORS`
*
* legacyDecorators behavior (default to enabled):
*
* - When this plugin is enabled, it's defaulted to legacy decorators behavior.
* - To change this behavior, set this option to `{ legacy: false }`
*/
proposalDecorators?: boolean | { legacy: boolean };

Expand All @@ -43,9 +51,13 @@ export type BabelOptions = {
/**
* Add `@babel/plugin-proposal-class-properties` for class properties support
* - **Default: `false`**
* - To use loose class props behavior, set it to `{ loose: true }`, which compile to
* assignment expression instead of `Object.defineProperty`.
* - if not set, then we check env `BABEL_CLASS_PROPS`
*
* looseClassProps behavior (default to enabled):
*
* - When this plugin is enabled, it's defaulted to loose class props setting, which compile to
* assignment expression instead of `Object.defineProperty`
* - To change loose class props behavior, set this option to `{ loose: false }`,
*/
transformClassProps?: boolean | { loose: boolean };

Expand Down
97 changes: 87 additions & 10 deletions packages/xarc-app-dev/src/config/options.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/* eslint-disable @typescript-eslint/no-var-requires */
export {};

const Path = require("path");
const optionalRequire = require("optional-require")(require);
const constants = require("./constants");
const utils = require("../lib/utils");
const _ = require("lodash");
const xenvConfig = require("xenv-config");
const makeAppMode = require("@xarc/app/lib/app-mode");

function checkOptArchetypeInAppDep(dependencies, isDev = undefined) {
export function checkOptArchetypeInAppDep(dependencies, isDev = undefined) {
const options = dependencies
.filter(x => x.startsWith("electrode-archetype-opt-") || x.startsWith("@xarc/opt-"))
.reduce((acc, name) => {
Expand Down Expand Up @@ -44,7 +45,7 @@ function checkOptArchetypeInAppDep(dependencies, isDev = undefined) {
return { options };
}

const getUserConfigOptions = (packageNames, devPackageNames) => {
export const getUserConfigOptions = (packageNames, devPackageNames) => {
return {
reactLib: "react",
karma: true,
Expand All @@ -63,7 +64,7 @@ const getUserConfigOptions = (packageNames, devPackageNames) => {
*
* @returns default options
*/
function getDefaultArchetypeOptions() {
export function getDefaultArchetypeOptions() {
//
// try to find application's package.json so we can check its dependencies
// and devDependencies for modules that enable add on features.
Expand All @@ -90,8 +91,84 @@ function getDefaultArchetypeOptions() {
};
}

module.exports = {
checkOptArchetypeInAppDep,
getUserConfigOptions,
getDefaultArchetypeOptions
};
/**
* Legacy way to gather development options from user set env, config files in archetype/config,
* and internal default values.
*
* Now all these can be passed in as a single options object when loading the dev tasks,
* but still support the legacy ones by using them as default.
*/
export function getDevArchetypeLegacy() {
const defaultArchetypeConfig = getDefaultArchetypeOptions();
const userConfig = defaultArchetypeConfig.options;

const webpack = require("./env-webpack")();
const babel = require("./env-babel")();
const karma = require("./env-karma")();

const { myPkg: devPkg, myDir: devDir } = utils.getMyPkg();
const configDir = Path.join(devDir, "config");
const devRequire = require(Path.join(devDir, "require"));

const config = {
...defaultArchetypeConfig,
devDir,
devPkg,
devRequire,
webpack,
karma,
jest: Object.assign({}, userConfig.jest),
babel,
config: {
babel: `${configDir}/babel`,
eslint: `${configDir}/eslint`,
karma: `${configDir}/karma`,
mocha: `${configDir}/mocha`,
webpack: `${configDir}/webpack`,
jest: `${configDir}/jest`,
...userConfig.configPaths
},
prodDir: constants.PROD_DIR,
eTmpDir: constants.ETMP_DIR,
AppMode: makeAppMode(constants.PROD_DIR, userConfig.reactLib)
};

const topConfigSpec = {
devOpenBrowser: { env: "ELECTRODE_DEV_OPEN_BROWSER", default: false }
};

const typeScriptOption =
userConfig.typescript === false
? {
babel: { enableTypeScript: userConfig.typescript }
}
: {};

const archetypeConfig = Object.assign(
_.merge(config, typeScriptOption),
xenvConfig(topConfigSpec, _.pick(userConfig, Object.keys(topConfigSpec)), { merge: _.merge })
);

archetypeConfig.babel.hasMultiTargets =
Object.keys(archetypeConfig.babel.envTargets)
.sort()
.join(",") !== "default,node";

let AppMode;

//
// AppMode could cause circular dependency loading
// Make it a get property so it's load after this file is processed
//
Object.defineProperty(archetypeConfig, "AppMode", {
get() {
if (!AppMode) {
AppMode = makeAppMode(archetypeConfig.prodDir, archetypeConfig.reactLib);
}

return AppMode;
}
});

return archetypeConfig;
}
Loading

0 comments on commit a1ad08d

Please sign in to comment.