api: extract browser-friendly build target (#1536)

Summary:
This re-packages the build for the internal APIs exposed under #1526 to
be more browser-friendly. Removing `target: "node"` (and adding an
explicit `globalObject: "this"` for best-effort cross-compatibility) is
the biggest change from the backend build; removing all the extra
loaders and static site generation is the biggest change from the
frontend build.

This build configuration is forked from `webpack.config.backend.js`.

Test Plan:
Run `yarn api`, then upload the contents of `dist/api.js` to an
Observable notebook and require it as an ES module. Verify that the
SourceCred APIs are exposed: e.g., `sourcecred.core.graph.Graph` should
be a valid constructor.

wchargin-branch: api-build
This commit is contained in:
William Chargin 2020-01-09 21:27:37 -08:00 committed by GitHub
parent be7b465f98
commit 8ed0585bb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 1 deletions

3
.gitignore vendored
View File

@ -12,6 +12,9 @@
# backend # backend
/bin /bin
# api
/dist
# misc # misc
data/ data/
.token .token

View File

@ -1,5 +1,6 @@
/bin /bin
/build /build
/coverage /coverage
/dist
/flow-typed /flow-typed
/sharness /sharness

View File

@ -20,6 +20,9 @@ module.exports = {
yarnLockFile: resolveApp("yarn.lock"), yarnLockFile: resolveApp("yarn.lock"),
appNodeModules: resolveApp("node_modules"), appNodeModules: resolveApp("node_modules"),
apiIndexJs: resolveApp("src/api/index.js"),
apiBuild: resolveApp("dist"),
backendBuild: resolveApp("bin"), backendBuild: resolveApp("bin"),
// This object should have one key-value pair per entry point. For // This object should have one key-value pair per entry point. For
// each key, the value should be the path to the entry point for the // each key, the value should be the path to the entry point for the
@ -27,7 +30,6 @@ module.exports = {
// point within the build directory. // point within the build directory.
backendEntryPoints: { backendEntryPoints: {
sourcecred: resolveApp("src/cli/main.js"), sourcecred: resolveApp("src/cli/main.js"),
api: resolveApp("src/api/index.js"),
// //
generateGithubGraphqlFlowTypes: resolveApp( generateGithubGraphqlFlowTypes: resolveApp(
"src/plugins/github/bin/generateGraphqlFlowTypes.js" "src/plugins/github/bin/generateGraphqlFlowTypes.js"

View File

@ -0,0 +1,75 @@
// @flow
// Do this as the first thing so that any code reading it knows the right env.
process.env.NODE_ENV = process.env.NODE_ENV || "development";
process.env.BABEL_ENV = process.env.NODE_ENV;
const webpack = require("webpack");
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");
const RemoveBuildDirectoryPlugin = require("./RemoveBuildDirectoryPlugin");
const paths = require("./paths");
const getClientEnvironment = require("./env");
const env = getClientEnvironment(null);
module.exports = {
// Don't attempt to continue if there are any errors.
bail: true,
node: {
// Don't munge `__dirname` and `__filename`.
// https://github.com/webpack/webpack/issues/1599#issuecomment-186841345
__dirname: false,
__filename: false,
},
entry: {
api: paths.apiIndexJs,
},
output: {
path: paths.apiBuild,
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
filename: "[name].js",
chunkFilename: "[name].[chunkhash:8].chunk.js",
libraryTarget: "umd",
library: "sourcecred",
// Use `this` for compatibility with both Node and browser.
globalObject: "this",
},
resolve: {
extensions: [".js", ".json"],
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
module: {
strictExportPresence: true,
rules: [
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. If no loader matches, it will fail.
oneOf: [
// Process JS with Babel.
{
test: /\.(js|jsx|mjs)$/,
include: paths.appSrc,
loader: require.resolve("babel-loader"),
options: {
compact: true,
},
},
],
},
],
},
plugins: [
new RemoveBuildDirectoryPlugin(),
new webpack.DefinePlugin(env.individuallyStringified),
],
mode: process.env.NODE_ENV,
};

View File

@ -92,6 +92,7 @@
"start": "NODE_ENV=development webpack-dev-server --config config/webpack.config.web.js", "start": "NODE_ENV=development webpack-dev-server --config config/webpack.config.web.js",
"build": "NODE_ENV=production webpack --config config/webpack.config.web.js", "build": "NODE_ENV=production webpack --config config/webpack.config.web.js",
"backend": "NODE_ENV=development webpack --config config/webpack.config.backend.js", "backend": "NODE_ENV=development webpack --config config/webpack.config.backend.js",
"api": "webpack --config config/webpack.config.api.js",
"test": "node ./config/test.js", "test": "node ./config/test.js",
"unit": "BABEL_ENV=test NODE_ENV=test jest --env=jsdom", "unit": "BABEL_ENV=test NODE_ENV=test jest --env=jsdom",
"sharness": "make -sC ./sharness prove PROVE_OPTS=-f TEST_OPTS='--chain-lint'", "sharness": "make -sC ./sharness prove PROVE_OPTS=-f TEST_OPTS='--chain-lint'",