Browse Source

build(js): Move build-platform-assets to webpack for FE builds (#13813)

With this patch, FE builds have no dependency on the main Sentry app.
Burak Yigit Kaya 5 years ago
parent
commit
07a64cc3cc

+ 0 - 1
Makefile

@@ -171,7 +171,6 @@ test-symbolicator:
 
 test-acceptance: node-version-check
 	sentry init
-	make build-platform-assets
 	@echo "--> Building static assets"
 	@$(WEBPACK) --display errors-only
 	@echo "--> Running acceptance tests"

+ 67 - 0
build-utils/integration-docs-fetch-plugin.js

@@ -0,0 +1,67 @@
+/*eslint-env node*/
+/*eslint import/no-nodejs-modules:0 */
+const fs = require('fs');
+const https = require('https');
+const path = require('path');
+
+const PLATFORMS_URL = 'https://docs.sentry.io/_platforms/_index.json';
+const DOCS_INDEX_PATH = 'src/sentry/integration-docs/_platforms.json';
+
+const alphaSortFromKey = keyExtractor => (a, b) =>
+  keyExtractor(a).localeCompare(keyExtractor(b));
+
+const transformPlatformsToList = ({platforms}) =>
+  Object.keys(platforms)
+    .map(platformId => {
+      const integrationMap = platforms[platformId];
+      const integrations = Object.keys(integrationMap)
+        .sort(alphaSortFromKey(key => integrationMap[key].name))
+        .map(integrationId => {
+          const {name, type, doc_link: link} = integrationMap[integrationId];
+          const id =
+            integrationId === '_self' ? platformId : `${platformId}-${integrationId}`;
+
+          return {id, name, type, link};
+        });
+      return {
+        id: platformId,
+        name: integrationMap._self.name,
+        integrations,
+      };
+    })
+    .sort(alphaSortFromKey(item => item.name));
+
+class IntegrationDocsFetchPlugin {
+  constructor({basePath}) {
+    this.modulePath = path.join(basePath, DOCS_INDEX_PATH);
+  }
+
+  apply(compiler) {
+    compiler.hooks.beforeRun.tapAsync(
+      'IntegrationDocsFetchPlugin',
+      (compilation, callback) => {
+        https
+          .get(PLATFORMS_URL, res => {
+            res.setEncoding('utf8');
+            let buffer = '';
+            res
+              .on('data', data => {
+                buffer += data;
+              })
+              .on('end', () =>
+                fs.writeFile(
+                  this.modulePath,
+                  JSON.stringify({
+                    platforms: transformPlatformsToList(JSON.parse(buffer)),
+                  }),
+                  callback
+                )
+              );
+          })
+          .on('error', callback);
+      }
+    );
+  }
+}
+
+module.exports = IntegrationDocsFetchPlugin;

+ 34 - 0
build-utils/optional-locale-chunk-plugin.js

@@ -0,0 +1,34 @@
+/*eslint-env node*/
+/*eslint import/no-nodejs-modules:0 */
+
+/**
+ * When our locales are codesplit into cache groups, webpack expects that all
+ * chunks *must* be loaded before the main entrypoint can be executed. However,
+ * since we will only be using one locale at a time we do not want to load all
+ * locale chunks, just the one the user has enabled.
+ *
+ * This plugin removes the locale chunks from the app entrypoint's immediate
+ * chunk dependants list, ensuring that the compiled entrypoint will execute
+ * *without* all locale chunks loaded.
+ */
+const PLUGIN_NAME = 'OptionalLocaleChunkPlugin';
+
+const clearLocaleChunks = chunks =>
+  chunks
+    .filter(chunk => chunk.name !== 'app')
+    .forEach(chunk => {
+      const mainGroup = Array.from(chunk.groupsIterable)[0];
+      mainGroup.chunks = mainGroup.chunks.filter(
+        c => c.name && !c.name.startsWith('locale')
+      );
+    });
+
+class OptionalLocaleChunkPlugin {
+  apply(compiler) {
+    compiler.hooks.compilation.tap(PLUGIN_NAME, compilation =>
+      compilation.hooks.afterOptimizeChunks.tap(PLUGIN_NAME, clearLocaleChunks)
+    );
+  }
+}
+
+module.exports = OptionalLocaleChunkPlugin;

+ 14 - 35
webpack.config.js

@@ -4,6 +4,8 @@ const path = require('path');
 const fs = require('fs');
 const webpack = require('webpack');
 const babelConfig = require('./babel.config');
+const OptionalLocaleChunkPlugin = require('./build-utils/optional-locale-chunk-plugin');
+const IntegrationDocsFetchPlugin = require('./build-utils/integration-docs-fetch-plugin');
 const ExtractTextPlugin = require('mini-css-extract-plugin');
 const CompressionPlugin = require('compression-webpack-plugin');
 const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
@@ -11,10 +13,10 @@ const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
 const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
 
 const {env} = process;
-
 const IS_PRODUCTION = env.NODE_ENV === 'production';
 const IS_TEST = env.NODE_ENV === 'test' || env.TEST_SUITE;
 const IS_STORYBOOK = env.STORYBOOK_BUILD === '1';
+
 const WEBPACK_MODE = IS_PRODUCTION ? 'production' : 'development';
 
 // HMR proxying
@@ -138,36 +140,6 @@ const localeRestrictionPlugins = [
   ),
 ];
 
-/**
- * When our locales are codesplit into cache groups, webpack expects that all
- * chunks *must* be loaded before the main entrypoint can be executed. However,
- * since we will only be using one locale at a time we do not want to load all
- * locale chunks, just the one the user has enabled.
- *
- * This plugin removes the locale chunks from the app entrypoint's immediate
- * chunk dependants list, ensuring the the compiled entrypoint will execute
- * *without* all locale chunks loaded.
- */
-const pluginName = 'OptionalLocaleChunkPlugin';
-
-const clearLocaleChunks = chunks =>
-  chunks
-    .filter(chunk => chunk.name !== 'app')
-    .forEach(chunk => {
-      const mainGroup = Array.from(chunk.groupsIterable)[0];
-      mainGroup.chunks = mainGroup.chunks.filter(
-        c => c.name && !c.name.startsWith('locale')
-      );
-    });
-
-class OptionalLocaleChunkPlugin {
-  apply(compiler) {
-    compiler.hooks.compilation.tap(pluginName, compilation =>
-      compilation.hooks.afterOptimizeChunks.tap(pluginName, clearLocaleChunks)
-    );
-  }
-}
-
 /**
  * Explicit codesplitting cache groups
  */
@@ -286,10 +258,6 @@ const appConfig = {
       app: path.join(staticPrefix, 'app'),
       'app-test': path.join(__dirname, 'tests', 'js'),
       'sentry-locale': path.join(__dirname, 'src', 'sentry', 'locale'),
-      'integration-docs-platforms':
-        IS_TEST || IS_STORYBOOK
-          ? path.join(__dirname, 'tests/fixtures/integration-docs/_platforms.json')
-          : path.join(__dirname, 'src/sentry/integration-docs/_platforms.json'),
     },
     modules: ['node_modules'],
     extensions: ['.jsx', '.js', '.json', '.ts', '.tsx'],
@@ -310,6 +278,17 @@ const appConfig = {
   devtool: IS_PRODUCTION ? 'source-map' : 'cheap-module-eval-source-map',
 };
 
+if (IS_TEST || IS_STORYBOOK) {
+  appConfig.resolve.alias['integration-docs-platforms'] = path.join(
+    __dirname,
+    'tests/fixtures/integration-docs/_platforms.json'
+  );
+} else {
+  const plugin = new IntegrationDocsFetchPlugin({basePath: __dirname});
+  appConfig.plugins.push(plugin);
+  appConfig.resolve.alias['integration-docs-platforms'] = plugin.modulePath;
+}
+
 /**
  * Legacy CSS Webpack appConfig for Django-powered views.
  * This generates a single "sentry.css" file that imports ALL component styles