Generate tsconfig once instead of on every webpack invocation
Avoids any potential race condition with parallel webpack invocations
This commit is contained in:
@@ -28,6 +28,8 @@ brave_common_web_compile_inputs = [
|
||||
|
||||
# webpack config changes warrant a re-build of all webpack builds
|
||||
rebase_path("../webpack/webpack.config.js"),
|
||||
rebase_path("../webpack/gen-webpack-grd.js"),
|
||||
rebase_path("../webpack/path-map.js"),
|
||||
rebase_path("../webpack/webpack-plugin-depfile.js"),
|
||||
|
||||
# typescript config changes warrant a re-build of all typescript builds
|
||||
@@ -83,6 +85,7 @@ template("transpile_web_ui") {
|
||||
|
||||
# make sure rebuilds when common files change
|
||||
inputs = brave_common_web_compile_inputs
|
||||
inputs += [ "$root_gen_dir/tsconfig-webpack.json" ]
|
||||
if (defined(invoker.inputs)) {
|
||||
inputs += invoker.inputs
|
||||
}
|
||||
@@ -90,7 +93,7 @@ template("transpile_web_ui") {
|
||||
deps = [
|
||||
# Ensure chrome://resources/js file and typescript definitions are
|
||||
# generated
|
||||
"//ui/webui/resources:library",
|
||||
"//brave/components/webpack:generate_tsconfig",
|
||||
]
|
||||
if (defined(invoker.deps)) {
|
||||
deps += invoker.deps
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
action("generate_tsconfig") {
|
||||
script = "//brave/script/generate-tsconfig.py"
|
||||
deps = [
|
||||
# Ensure chrome://resources/js file and typescript definitions are
|
||||
# generated
|
||||
"//ui/webui/resources:library",
|
||||
]
|
||||
inputs = [
|
||||
"gen-tsconfig.js",
|
||||
"path-map.js",
|
||||
]
|
||||
outputs = [ "$root_gen_dir/tsconfig-webpack.json" ]
|
||||
args = [ "--root_gen_dir=" + rebase_path(root_gen_dir) ]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const pathMap = require('./path-map')
|
||||
|
||||
const srcPath = path.resolve(__dirname, '../../../')
|
||||
const braveSrcPath = path.join(srcPath, 'brave')
|
||||
|
||||
/**
|
||||
* Generates a tsconfig.json file in the gen/ directory
|
||||
* so that typescript can import files from cthe current build's
|
||||
* gen/ directory (e.g. mojom-generated JS).
|
||||
*
|
||||
* @param {*} [atPath=process.env.ROOT_GEN_DIR]
|
||||
* @returns void
|
||||
*/
|
||||
async function createGenTsConfig (atPath = process.env.ROOT_GEN_DIR) {
|
||||
const configExtendsFrom = path.relative(
|
||||
atPath,
|
||||
path.join(braveSrcPath, 'tsconfig-webpack.json')
|
||||
)
|
||||
const tsConfigPath = path.join(atPath, 'tsconfig-webpack.json')
|
||||
// Even though ts-loader will get the paths from webpack for module resolution
|
||||
// that does not help some issues where chromium both generates ts definitions
|
||||
// and has JSDoc comments for the .m.js file. Sometimes the JSDoc is incorrect
|
||||
// whilst the associated .d.ts file has the correct definition. Without specifying
|
||||
// the path mapping in the tsconfig.json, Typescript (via ts-loader) will use
|
||||
// the JSDoc, and fail with an error. The example that prompted this is cr.sendWithPromise
|
||||
// where Typescript will not see that the second parameter is an optional spread param
|
||||
// and will fail with an error. Whilst this should be fixed in the chromium source,
|
||||
// it's better to be explicit here so that developers get the same experience at
|
||||
// both compile and design time.
|
||||
const paths = {}
|
||||
for (const path in pathMap) {
|
||||
paths[`${path}/*`] = [`${pathMap[path]}/*`]
|
||||
}
|
||||
const config = {
|
||||
extends: configExtendsFrom,
|
||||
compilerOptions: {
|
||||
paths
|
||||
},
|
||||
references: [
|
||||
{
|
||||
// This ts project is generated by //ui/webui/resources:library
|
||||
path: path.join(atPath, 'ui/webui/resources/tsconfig.json')
|
||||
}
|
||||
]
|
||||
}
|
||||
await fs.writeFile(tsConfigPath, JSON.stringify(config))
|
||||
return tsConfigPath
|
||||
}
|
||||
|
||||
createGenTsConfig()
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2021 The Brave Authors. All rights reserved.
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
// Find files in the current build configurations /gen directory
|
||||
'gen': process.env.ROOT_GEN_DIR,
|
||||
// Generated resources at this path are available at chrome://resources and
|
||||
// whilst webpack will still bundle, we keep the alias to the served path
|
||||
// to minimize knowledge of specific gen/ paths and easily allow us to not bundle
|
||||
// them in the future for certain build configurationa, just like chromium.
|
||||
'chrome://resources': path.join(process.env.ROOT_GEN_DIR, 'ui/webui/resources/preprocessed'),
|
||||
// We import brave-ui direct from source and not from package repo, so we need
|
||||
// direct path to the src/ directory.
|
||||
'brave-ui': path.resolve(__dirname, '../../node_modules/brave-ui/src'),
|
||||
// Force same styled-components module for brave-core and brave-ui
|
||||
// which ensure both repos code use the same singletons, e.g. ThemeContext.
|
||||
'styled-components': path.resolve(__dirname, '../../node_modules/styled-components'),
|
||||
}
|
||||
@@ -4,77 +4,14 @@
|
||||
// you can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
const path = require('path')
|
||||
const GenerateDepfilePlugin = require('./webpack-plugin-depfile')
|
||||
const fs = require('fs-extra')
|
||||
const webpack = require('webpack')
|
||||
const GenerateDepfilePlugin = require('./webpack-plugin-depfile')
|
||||
const pathMap = require('./path-map')
|
||||
|
||||
const srcPath = path.resolve(__dirname, '../../../')
|
||||
const braveSrcPath = path.join(srcPath, 'brave')
|
||||
|
||||
const pathMap = {
|
||||
// Find files in the current build configurations /gen directory
|
||||
'gen': process.env.ROOT_GEN_DIR,
|
||||
// Generated resources at this path are available at chrome://resources and
|
||||
// whilst webpack will still bundle, we keep the alias to the served path
|
||||
// to minimize knowledge of specific gen/ paths and easily allow us to not bundle
|
||||
// them in the future for certain build configurationa, just like chromium.
|
||||
'chrome://resources': path.join(process.env.ROOT_GEN_DIR, 'ui/webui/resources/preprocessed'),
|
||||
// We import brave-ui direct from source and not from package repo, so we need
|
||||
// direct path to the src/ directory.
|
||||
'brave-ui': path.resolve(__dirname, '../../node_modules/brave-ui/src'),
|
||||
// Force same styled-components module for brave-core and brave-ui
|
||||
// which ensure both repos code use the same singletons, e.g. ThemeContext.
|
||||
'styled-components': path.resolve(__dirname, '../../node_modules/styled-components'),
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a tsconfig.json file in the gen/ directoryc
|
||||
* so that typescript can import files from cthe current build's
|
||||
* gen/ directory (e.g. mojom-generated JS).
|
||||
*
|
||||
* @param {*} [atPath=process.env.ROOT_GEN_DIR]
|
||||
* @returns void
|
||||
*/
|
||||
async function createGenTsConfig (atPath = process.env.ROOT_GEN_DIR) {
|
||||
const configExtendsFrom = path.relative(
|
||||
atPath,
|
||||
path.join(braveSrcPath, 'tsconfig-webpack.json')
|
||||
)
|
||||
const tsConfigPath = path.join(atPath, 'tsconfig.json')
|
||||
// Even though ts-loader will get the paths from webpack for module resolution
|
||||
// that does not help some issues where chromium both generates ts definitions
|
||||
// and has JSDoc comments for the .m.js file. Sometimes the JSDoc is incorrect
|
||||
// whilst the associated .d.ts file has the correct definition. Without specifying
|
||||
// the path mapping in the tsconfig.json, Typescript (via ts-loader) will use
|
||||
// the JSDoc, and fail with an error. The example that prompted this is cr.sendWithPromise
|
||||
// where Typescript will not see that the second parameter is an optional spread param
|
||||
// and will fail with an error. Whilst this should be fixed in the chromium source,
|
||||
// it's better to be explicit here so that developers get the same experience at
|
||||
// both compile and design time.
|
||||
const paths = {}
|
||||
for (const path in pathMap) {
|
||||
paths[`${path}/*`] = [`${pathMap[path]}/*`]
|
||||
}
|
||||
const config = {
|
||||
extends: configExtendsFrom,
|
||||
compilerOptions: {
|
||||
paths
|
||||
},
|
||||
references: [
|
||||
{
|
||||
// This ts project is generated by //ui/webui/resources:library
|
||||
path: path.join(atPath, 'ui/webui/resources/tsconfig.json')
|
||||
}
|
||||
]
|
||||
}
|
||||
await fs.writeFile(tsConfigPath, JSON.stringify(config))
|
||||
return tsConfigPath
|
||||
}
|
||||
const tsConfigPath = path.join(process.env.ROOT_GEN_DIR, 'tsconfig-webpack.json')
|
||||
|
||||
module.exports = async function (env, argv) {
|
||||
// TODO(petemill): only do this once per build, in a separate target
|
||||
// which the webpack targets depend on.
|
||||
const tsConfigPath = await createGenTsConfig()
|
||||
// Webpack config object
|
||||
return {
|
||||
devtool: argv.mode === 'development' ? '#inline-source-map' : false,
|
||||
@@ -109,9 +46,8 @@ module.exports = async function (env, argv) {
|
||||
options: {
|
||||
getCustomTransformers: path.join(__dirname, './webpack-ts-transformers.js'),
|
||||
allowTsInNodeModules: true,
|
||||
// TODO(petemill): generate in gen/ directory with baseUrl back to src/brave
|
||||
// - that would remove any problems with TS analyzing types in an incorrect
|
||||
// output directory (e.g. Static/ instead of Component/)
|
||||
// Use generated tsconfig so that we can point at gen/ output in the
|
||||
// correct build configuration output directory.
|
||||
configFile: tsConfigPath
|
||||
}
|
||||
},
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"pep8": "pycodestyle --max-line-length 120 -r script",
|
||||
"pylint": "node ./build/commands/scripts/commands.js pylint",
|
||||
"web-ui-gen-grd": "node components/webpack/gen-webpack-grd",
|
||||
"web-ui-gen-tsconfig": "node components/webpack/gen-tsconfig",
|
||||
"web-ui": "webpack --config components/webpack/webpack.config.js --colors",
|
||||
"build-storybook": "build-storybook -c .storybook -o .storybook-out",
|
||||
"storybook": "start-storybook",
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
from lib.util import execute_stdout, scoped_cwd
|
||||
|
||||
|
||||
NPM = 'npm'
|
||||
if sys.platform in ['win32', 'cygwin']:
|
||||
NPM += '.cmd'
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
root_gen_dir = args.root_gen_dir[0]
|
||||
generate_tsconfig(root_gen_dir)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='Generate tsconfig')
|
||||
parser.add_argument('--root_gen_dir', nargs=1)
|
||||
args = parser.parse_args()
|
||||
# validate args
|
||||
if (args.root_gen_dir is None or
|
||||
len(args.root_gen_dir) != 1 or
|
||||
len(args.root_gen_dir[0]) == 0):
|
||||
raise Exception("root_gen_dir argument was not specified correctly")
|
||||
# args are valid
|
||||
return args
|
||||
|
||||
def generate_tsconfig(root_gen_dir, env=None):
|
||||
if env is None:
|
||||
env = os.environ.copy()
|
||||
|
||||
args = [NPM, 'run', 'web-ui-gen-tsconfig']
|
||||
|
||||
env["ROOT_GEN_DIR"] = root_gen_dir
|
||||
|
||||
dirname = os.path.abspath(os.path.join(__file__, '..', '..'))
|
||||
with scoped_cwd(dirname):
|
||||
execute_stdout(args, env)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user