Explicit Browser Support (#1682)

* add FastestSmallestTextEncoderDecoder polyfill

* remove nomodule from script import

* add browserslist

* add obsolete-webpack-plugin

* switch out modern-browser for preset-env

* add prompt on non target browser

* propagate prod changes to dev

* add core-js-3 and TextEncoder TextDecoder (#1671)

* add script to remove react, style html

* propagate changes to prod

* add script-ext-html-webpack-plugin for async

* more styling

* add eslint-plugin-compat

* extend compat plugin

* add existing polyfills

* add github fetch polyfill

* add AbortController polyfill

* change promptOnNonTargetBrowser to false

* propagate

* add browser links

* prettier

* add browser support to readme

* move polyfills to webpack

* remove CDN encoder polyfill

* Add no Explorer support

* fix incorrect package name

* propagate changes

* Update README.md

Co-authored-by: Ambrose J Carr <ambrosejcarr@users.noreply.github.com>

* add new deps

* create shared config

* swap out html-loader for filestream

* sanitize template

Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com>
Co-authored-by: Ambrose J Carr <ambrosejcarr@users.noreply.github.com>
This commit is contained in:
Severiano Badajoz
2020-08-03 12:50:09 -07:00
committed by GitHub
co-authored by Ambrose J Carr Timmy Huang
parent ce13a9c7ca
commit 8bbc183647
12 changed files with 482 additions and 105 deletions
+8 -1
View File
@@ -2,7 +2,14 @@ module.exports = {
babelrc: false,
cacheDirectory: true,
presets: [
["modern-browsers", { loose: true, modules: false }],
[
"@babel/preset-env",
{
useBuiltIns: "entry",
corejs: 3,
modules: false,
},
],
"@babel/preset-react",
],
plugins: [
+8 -1
View File
@@ -1,7 +1,14 @@
module.exports = {
babelrc: false,
presets: [
["modern-browsers", { loose: true, modules: false }],
[
"@babel/preset-env",
{
useBuiltIns: "entry",
corejs: 3,
modules: false,
},
],
"@babel/preset-react",
],
plugins: [
+12
View File
@@ -4,9 +4,21 @@ module.exports = {
extends: [
"airbnb",
"plugin:eslint-comments/recommended",
"plugin:compat/recommended",
"plugin:prettier/recommended",
"prettier/react",
],
settings: {
polyfills: [
"TextDecoder",
"TextEncoder",
"fetch",
"Request",
"Response",
"Headers",
"AbortController",
],
},
env: { browser: true, commonjs: true, es6: true },
globals: {
expect: true,
@@ -0,0 +1,81 @@
<script>
var root = document.getElementById("root");
root.remove();
var portals = document.getElementsByClassName("bp3-portal");
for (var i = 0; i < portals.length; i += 1) {
portals[i].remove();
}
</script>
<div
style="
display: flex;
flex-direction: column;
width: 100vw;
height: 100vh;
text-align: center;
justify-content: center;
align-items: center;
background: #8080801a;
font-family: 'Roboto Condensed, sans serif';
"
>
<img
src="https://raw.githubusercontent.com/chanzuckerberg/cellxgene/main/docs/cellxgene-logo.png"
style="width: 320px;"
/>
<div
style="
margin-top: 16px;
background: white;
width: 40vw;
border-radius: 4px;
padding: 24px 64px;
-webkit-box-shadow: 0px 0px 3px 2px rgba(0, 0, 0, 0.38);
-moz-box-shadow: 0px 0px 3px 2px rgba(0, 0, 0, 0.38);
box-shadow: 0px 0px 3px 2px rgba(0, 0, 0, 0.38);
max-width: 550px;
"
>
<div style="margin-bottom: 0; font-weight: bolder; font-size: 1.2em;">
Unsupported Browser
</div>
<div style="margin-top: 0;">
cellxgene is currently supported on the following browsers
</div>
<div
style="display: flex; justify-content: space-around; margin-top: 16px;"
>
<a
href="https://www.google.com/chrome/?hl=en%22"
aria-label="Download Google Chrome"
>
<img
src="https://assets.beta.meta.org/images/browsers/chrome.png"
style="width: 80px; height: 80px;"
/>
<div>Chrome &gt; 60</div>
</a>
<a href="https://www.apple.com/safari/" aria-label="Download Safari">
<img
src="https://assets.beta.meta.org/images/browsers/safari.png"
style="width: 80px; height: 80px;"
/>
<div>Safari ≥ 10.1</div>
</a>
<a href="https://www.mozilla.com/firefox/" aria-label="Download Firefox">
<img
src="https://assets.beta.meta.org/images/browsers/firefox.png"
style="width: 80px; height: 80px;"
/>
<div>Firefox ≥ 60</div>
</a>
<a href="//www.microsoft.com/edge" aria-label="Download Edge">
<img
src="https://assets.beta.meta.org/images/browsers/edge.png"
style="width: 80px; height: 80px;"
/>
<div>Edge ≥ 15</div>
</a>
</div>
</div>
</div>
@@ -1,65 +1,32 @@
// jshint esversion: 6
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const FaviconsWebpackPlugin = require("favicons-webpack-plugin");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { merge } = require("webpack-merge");
const sharedConfig = require("./webpack.config.shared");
const babelOptions = require("../babel/babel.dev");
const src = path.resolve("src");
const fonts = path.resolve("src/fonts");
const nodeModules = path.resolve("node_modules");
const babelOptions = require("../babel/babel.dev");
module.exports = {
const devConfig = {
mode: "development",
devtool: "eval",
entry: ["./src/index"],
output: {
path: path.resolve("build"),
pathinfo: true,
filename: "static/js/bundle.js",
publicPath: "/",
},
module: {
rules: [
{
test: /\.js$/,
include: src,
test: /\.jsx?$/,
loader: "babel-loader",
options: babelOptions,
},
{
test: /\.css$/,
include: src,
exclude: [path.resolve(src, "index.css")],
loader: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
},
},
],
},
{
test: /index\.css$/,
include: [path.resolve(src, "index.css")],
loader: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
],
},
{ test: /\.json$/, include: [src, nodeModules], loader: "json-loader" },
{
test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2|otf)$/i,
loader: "file-loader",
@@ -88,6 +55,9 @@ module.exports = {
},
},
}),
new MiniCssExtractPlugin({
filename: "static/[name].css",
}),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
__REACT_DEVTOOLS_GLOBAL_HOOK__: "({ isDisabled: true })",
@@ -97,5 +67,10 @@ module.exports = {
process.env.CXG_SERVER_PORT
),
}),
new ScriptExtHtmlWebpackPlugin({
async: "obsolete",
}),
],
};
module.exports = merge(sharedConfig, devConfig);
@@ -1,32 +1,28 @@
// jshint esversion: 6
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const FaviconsWebpackPlugin = require("favicons-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const TerserJSPlugin = require("terser-webpack-plugin");
const CleanCss = require("clean-css");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const FaviconsWebpackPlugin = require("favicons-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CspHashPlugin = require("./cspHashPlugin");
const src = path.resolve("src");
const fonts = path.resolve("src/fonts");
const nodeModules = path.resolve("node_modules");
const { merge } = require("webpack-merge");
const babelOptions = require("../babel/babel.prod");
const publicPath = "/";
const CspHashPlugin = require("./cspHashPlugin");
const sharedConfig = require("./webpack.config.shared");
module.exports = {
const fonts = path.resolve("src/fonts");
const nodeModules = path.resolve("node_modules");
const prodConfig = {
mode: "production",
bail: true,
cache: false,
entry: ["./src/index.js"],
output: {
filename: "static/[name]-[contenthash].js",
path: path.resolve("build"),
publicPath,
},
optimization: {
minimize: true,
@@ -41,39 +37,10 @@ module.exports = {
module: {
rules: [
{
test: /\.js$/,
include: src,
test: /\.jsx?$/,
loader: "babel-loader",
options: babelOptions,
},
{
test: /\.css$/,
include: src,
exclude: [path.resolve(src, "index.css")],
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
importLoaders: 1,
},
},
],
},
{
test: /index\.css$/,
include: [path.resolve(src, "index.css")],
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.json$/,
include: [src, nodeModules],
loader: "json-loader",
exclude: /manifest.json$/,
},
{
test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2|otf)$/i,
loader: "file-loader",
@@ -121,3 +88,5 @@ module.exports = {
maxAssetSize: 2000000,
},
};
module.exports = merge(sharedConfig, prodConfig);
@@ -0,0 +1,74 @@
const path = require("path");
const fs = require("fs");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ObsoleteWebpackPlugin = require("obsolete-webpack-plugin");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const src = path.resolve("src");
const nodeModules = path.resolve("node_modules");
const publicPath = "/";
const rawObsoleteHTMLTemplate = fs.readFileSync(
`${__dirname}/obsoleteHTMLTemplate.html`,
"utf8"
);
const obsoleteHTMLTemplate = rawObsoleteHTMLTemplate.replace(/'/g, '"');
module.exports = {
entry: [
"core-js",
"regenerator-runtime/runtime",
"fastestsmallesttextencoderdecoder",
"whatwg-fetch",
"abort-controller/polyfill",
"./src/index",
],
output: {
path: path.resolve("build"),
publicPath,
},
module: {
rules: [
{
test: /\.css$/,
include: src,
exclude: [path.resolve(src, "index.css")],
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
importLoaders: 1,
},
},
],
},
{
test: /index\.css$/,
include: [path.resolve(src, "index.css")],
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.json$/,
include: [src, nodeModules],
loader: "json-loader",
exclude: /manifest.json$/,
},
],
},
plugins: [
new ObsoleteWebpackPlugin({
name: "obsolete",
template: obsoleteHTMLTemplate,
promptOnNonTargetBrowser: false,
}),
new ScriptExtHtmlWebpackPlugin({
async: "obsolete",
}),
],
};