From 014eb203c31070420841beae3921869d699e91be Mon Sep 17 00:00:00 2001 From: SirStendec Date: Wed, 19 Jun 2019 20:57:14 -0400 Subject: [PATCH] The Great Webpack Update. * Update to version 4 of webpack. * For that matter, update *every dependency* to the latest available version. * Remove the babel build target for Edge, as it doesn't seem to be necessary with webpack 4 and tenser. * Add support for optional chaining and nullish coalescing via Babel transformations. * Update the clips domain version to work better. Or at all, really. * Remove unused code from i18n. * Remove the last ` + \ No newline at end of file diff --git a/src/raven.js b/src/raven.js index 4e1274db..a0320355 100644 --- a/src/raven.js +++ b/src/raven.js @@ -176,7 +176,7 @@ export default class RavenLogger extends Module { const exc = data.exception && data.exception.values[0]; // We don't want any of Sentry's junk. - if ( data.message && data.messages.includes('raven-js/') || (exc && JSON.stringify(exc).includes('raven-js/')) ) + if ( data.message && data.message.includes('raven-js/') || (exc && JSON.stringify(exc).includes('raven-js/')) ) return false; // We don't want any of Mozilla's junk either. diff --git a/src/sites/twitch-clips/index.js b/src/sites/twitch-clips/index.js index 9c7450a0..78bd03fb 100644 --- a/src/sites/twitch-clips/index.js +++ b/src/sites/twitch-clips/index.js @@ -29,7 +29,7 @@ export default class Clippy extends BaseSite { this.inject(Fine); this.inject(Apollo, false); - this.inject(Switchboard); + //this.inject(Switchboard); } onLoad() { diff --git a/src/sites/twitch-clips/modules/chat/index.js b/src/sites/twitch-clips/modules/chat/index.js index 57e58732..fd2549a6 100644 --- a/src/sites/twitch-clips/modules/chat/index.js +++ b/src/sites/twitch-clips/modules/chat/index.js @@ -49,6 +49,7 @@ export default class Chat extends Module { this.ChatController.on('mount', this.chatMounted, this); this.ChatController.on('unmount', this.chatMounted, this); + this.ChatController.on('update', this.chatUpdated, this); this.ChatController.on('receive-props', this.chatUpdated, this); this.ChatController.ready((cls, instances) => { @@ -167,7 +168,7 @@ export default class Chat extends Module { chatUpdated(chat, props) { - if ( get('data.clip.broadcaster.id', props) !== get('data.clip.broadcaster.id', chat.props) ) { + if ( ! chat._ffz_room || props?.data?.clip?.broadcaster?.id !== chat._ffz_room.id ) { this.chatUmounted(chat); this.chatMounted(chat, props); return; diff --git a/src/sites/twitch-clips/modules/css_tweaks/index.js b/src/sites/twitch-clips/modules/css_tweaks/index.js index 7aa7a059..47be03db 100644 --- a/src/sites/twitch-clips/modules/css_tweaks/index.js +++ b/src/sites/twitch-clips/modules/css_tweaks/index.js @@ -82,7 +82,7 @@ export default class CSSTweaks extends Module { const raw = (await import(/* webpackChunkName: "site-css-tweaks" */ './styles.js')).default; for(const key of raw.keys()) { const k = key.slice(2, key.length - (key.endsWith('.scss') ? 5 : 4)); - this.chunks[k] = raw(key); + this.chunks[k] = raw(key).default; } this.chunks_loaded = true; diff --git a/src/sites/twitch-twilight/modules/channel_bar.jsx b/src/sites/twitch-twilight/modules/channel_bar.jsx index e364e512..c99d31be 100644 --- a/src/sites/twitch-twilight/modules/channel_bar.jsx +++ b/src/sites/twitch-twilight/modules/channel_bar.jsx @@ -163,7 +163,7 @@ export default class ChannelBar extends Module { updateMetadata(inst, keys) { const container = this.fine.getChildNode(inst), - metabar = container && container.querySelector && container.querySelector('.channel-info-bar__action-container > .tw-flex,.channel-info-bar__content-right > .tw-align-items-start > .tw-flex:last-child'); + metabar = container?.querySelector?.('.channel-info-bar__action-container > .tw-flex,.channel-info-bar__content-right > .tw-align-items-start > .tw-flex:last-child'); if ( ! inst._ffz_mounted || ! metabar ) return; diff --git a/src/sites/twitch-twilight/modules/css_tweaks/index.js b/src/sites/twitch-twilight/modules/css_tweaks/index.js index ab68a870..76a43d39 100644 --- a/src/sites/twitch-twilight/modules/css_tweaks/index.js +++ b/src/sites/twitch-twilight/modules/css_tweaks/index.js @@ -332,7 +332,7 @@ export default class CSSTweaks extends Module { const raw = (await import(/* webpackChunkName: "site-css-tweaks" */ './styles.js')).default; for(const key of raw.keys()) { const k = key.slice(2, key.length - (key.endsWith('.scss') ? 5 : 4)); - this.chunks[k] = raw(key); + this.chunks[k] = raw(key).default; } this.chunks_loaded = true; diff --git a/src/sites/twitch-twilight/modules/menu_button.jsx b/src/sites/twitch-twilight/modules/menu_button.jsx index 539e6a6a..6cbb2fcc 100644 --- a/src/sites/twitch-twilight/modules/menu_button.jsx +++ b/src/sites/twitch-twilight/modules/menu_button.jsx @@ -118,7 +118,11 @@ export default class MenuButton extends SiteModule { if ( ! container ) return; - const user_stuff = container.querySelector(':scope > .tw-justify-content-end:last-child'); + let user_stuff = null; + try { + user_stuff = container.querySelector(':scope > .tw-justify-content-end:last-child'); + } catch(err) { /* dumb browsers with no :scope are dumb */ } + if ( user_stuff ) container = user_stuff; else diff --git a/src/std-components/icon-picker.vue b/src/std-components/icon-picker.vue index c62e1d43..4d752f62 100644 --- a/src/std-components/icon-picker.vue +++ b/src/std-components/icon-picker.vue @@ -7,8 +7,8 @@
-
+
reg.test(x[1])); }, diff --git a/src/std-components/markdown.vue b/src/std-components/markdown.vue index e5aee71b..881e50ce 100644 --- a/src/std-components/markdown.vue +++ b/src/std-components/markdown.vue @@ -1,4 +1,5 @@ diff --git a/src/utilities/compat/webmunch.js b/src/utilities/compat/webmunch.js index ae4b0801..3cb56f98 100644 --- a/src/utilities/compat/webmunch.js +++ b/src/utilities/compat/webmunch.js @@ -6,7 +6,7 @@ // ============================================================================ import Module from 'utilities/module'; -import {has, once} from 'utilities/object'; +import {has} from 'utilities/object'; let last_muncher = 0; diff --git a/src/utilities/time.js b/src/utilities/time.js index 65df2367..7f955be4 100644 --- a/src/utilities/time.js +++ b/src/utilities/time.js @@ -32,8 +32,8 @@ export function duration_to_string(elapsed, separate_days, days_only, no_hours, export function print_duration(seconds) { - let minutes = Math.floor(seconds / 60), - hours = Math.floor(minutes / 60); + let minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); minutes %= 60; seconds %= 60; diff --git a/src/utilities/translation-core.js b/src/utilities/translation-core.js index 56cea45e..18b8b128 100644 --- a/src/utilities/translation-core.js +++ b/src/utilities/translation-core.js @@ -445,7 +445,7 @@ export default class TranslationCore { if ( locale == null ) locale = this.locale; - let val = get(node.v, data); + const val = get(node.v, data); if ( val == null ) return null; diff --git a/src/utilities/twitch-data.js b/src/utilities/twitch-data.js index 0b2163ee..cbd5ec9c 100644 --- a/src/utilities/twitch-data.js +++ b/src/utilities/twitch-data.js @@ -173,7 +173,7 @@ export default class TwitchData extends Module { // ======================================================================== getStreamMeta(id, login) { - return new Promise(async (s, f) => { + return new Promise((s, f) => { if ( id ) { if ( this._waiting_stream_ids.has(id) ) this._waiting_stream_ids.get(id).push([s, f]); diff --git a/styles/widgets.scss b/styles/widgets.scss index a34bb6dc..76a411c6 100644 --- a/styles/widgets.scss +++ b/styles/widgets.scss @@ -279,4 +279,24 @@ textarea.tw-input { .ffz--button-disable { @include button-colors(#bd0f0f, #fff, 6px); +} + +.ffz--example-report { + div { + max-height: 30rem; + overflow-y: auto; + + code { + font-family: monospace; + white-space: pre-wrap; + word-break: break-all; + } + } +} + +.ffz--report-upload { + z-index: 1; + position: absolute; + top: 1rem; + right: 3rem; } \ No newline at end of file diff --git a/webpack.clips.babel.js b/webpack.clips.babel.js deleted file mode 100644 index 5a04a021..00000000 --- a/webpack.clips.babel.js +++ /dev/null @@ -1,82 +0,0 @@ -const webpack = require('webpack'); -const merge = require('webpack-merge'); -const common = require('./webpack.clips.common.js'); -const path = require('path'); - -const CleanPlugin = require('clean-webpack-plugin'); -const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); -const ManifestPlugin = require('webpack-manifest-plugin'); - -const commit_hash = require('child_process').execSync('git rev-parse HEAD').toString().trim(); - -/* global module __dirname */ - -const config = module.exports = merge(common, { - devtool: 'source-map', - - module: { - rules: [{ - test: /\.jsx?$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - plugins: ['transform-es2015-classes'] - } - } - }] - }, - - plugins: [ - new CleanPlugin(['dist/clips/babel']), - new UglifyJSPlugin({ - sourceMap: true, - uglifyOptions: { - compress: { - keep_fnames: true, - keep_classnames: true - }, - mangle: { - keep_classnames: true, - keep_fnames: true - } - } - }), - new webpack.DefinePlugin({ - __git_commit__: JSON.stringify(commit_hash) - }), - new ManifestPlugin({ - basePath: 'clips/babel/', - publicPath: 'clips/babel/', - map: data => { - if ( data.name.endsWith('.scss') ) - data.name = `${data.name.substr(0,data.name.length - 5)}.css`; - - return data; - } - }) - ], - - output: { - publicPath: '//cdn.frankerfacez.com/static/clips/babel/', - path: path.resolve(__dirname, 'dist/clips/babel'), - filename: '[name].[hash].js' - } -}); - - -// This is why we can't have nice things. -// Why can't I just access process.env.NODE_ENV from -// one of these files when I set it with webpack's -// CLI? So stupid. -// -// So here we go. -// This is crap. -// But it works. - -for(const rule of config.module.rules) { - if ( Array.isArray(rule.use) ) - for(const use of rule.use) - if ( use.options && use.options.name && use.options.name.startsWith('[name].') ) - use.options.name = `[name].[hash].${use.options.name.slice(7)}`; -} \ No newline at end of file diff --git a/webpack.clips.dev.js b/webpack.clips.dev.js index 079dcb7d..f0962a24 100644 --- a/webpack.clips.dev.js +++ b/webpack.clips.dev.js @@ -9,6 +9,7 @@ const webpack = require('webpack'); /* global module */ module.exports = merge(common, { + mode: 'development', devtool: 'inline-source-map', plugins: [ @@ -39,7 +40,7 @@ module.exports = merge(common, { proxy: { '**': { - target: 'http://cdn.frankerfacez.com/', + target: 'https://cdn.frankerfacez.com/', changeOrigin: true } }, @@ -68,6 +69,7 @@ module.exports = merge(common, { output: { publicPath: '//localhost:8000/script/clips/', filename: '[name].js', - jsonpFunction: 'ffzWebpackJsonp' + jsonpFunction: 'ffzWebpackJsonp', + crossOriginLoading: 'anonymous' } }) \ No newline at end of file diff --git a/webpack.clips.prod.js b/webpack.clips.prod.js index 15efdf79..453b7c84 100644 --- a/webpack.clips.prod.js +++ b/webpack.clips.prod.js @@ -4,11 +4,11 @@ const common = require('./webpack.clips.common.js'); const path = require('path'); const CopyPlugin = require('copy-webpack-plugin'); -const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); -const CleanPlugin = require('clean-webpack-plugin'); +const {CleanWebpackPlugin} = require('clean-webpack-plugin'); -const uglify = require('uglify-es'); +const Terser = require('terser'); // Get Git info @@ -16,24 +16,25 @@ const commit_hash = require('child_process').execSync('git rev-parse HEAD').toSt /* global module Buffer __dirname */ -const config = module.exports = merge(common, { +module.exports = merge(common, { + mode: 'production', devtool: 'source-map', - plugins: [ - new CleanPlugin(['dist/clips']), - new UglifyJSPlugin({ - sourceMap: true, - uglifyOptions: { - compress: { - keep_fnames: true, - keep_classnames: true - }, - mangle: { + optimization: { + concatenateModules: false, + minimizer: [ + new TerserPlugin({ + sourceMap: true, + terserOptions: { keep_classnames: true, keep_fnames: true } - } - }), + }) + ] + }, + + plugins: [ + new CleanWebpackPlugin(), new webpack.DefinePlugin({ __git_commit__: JSON.stringify(commit_hash) }), @@ -43,7 +44,7 @@ const config = module.exports = merge(common, { to: 'script.min.js', transform: content => { const text = content.toString('utf8'); - const minified = uglify.minify(text); + const minified = Terser.minify(text); return (minified && minified.code) ? Buffer.from(minified.code) : content; } } @@ -65,21 +66,4 @@ const config = module.exports = merge(common, { path: path.resolve(__dirname, 'dist/clips'), filename: '[name].[hash].js' } -}); - - -// This is why we can't have nice things. -// Why can't I just access process.env.NODE_ENV from -// one of these files when I set it with webpack's -// CLI? So stupid. -// -// So here we go. -// This is crap. -// But it works. - -for(const rule of config.module.rules) { - if ( Array.isArray(rule.use) ) - for(const use of rule.use) - if ( use.options && use.options.name && use.options.name.startsWith('[name].') ) - use.options.name = `[name].[hash].${use.options.name.slice(7)}`; -} \ No newline at end of file +}); \ No newline at end of file diff --git a/webpack.common.js b/webpack.common.js index 025f80c1..e1f95b77 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,7 +1,11 @@ const webpack = require('webpack'); const path = require('path'); -/* global module __dirname */ +const VueLoaderPlugin = require('vue-loader/lib/plugin'); + +/* global process module __dirname */ + +const PRODUCTION = process.env.NODE_ENV === 'production'; module.exports = { entry: { @@ -30,7 +34,15 @@ module.exports = { jsonpFunction: 'ffzWebpackJsonp', crossOriginLoading: 'anonymous' }, + optimization: { + splitChunks: { + cacheGroups: { + vendors: false + } + } + }, plugins: [ + new VueLoaderPlugin(), new webpack.ExtendedAPIPlugin() ], module: { @@ -39,7 +51,7 @@ module.exports = { use: [{ loader: 'file-loader', options: { - name: '[name].css' + name: PRODUCTION ? '[name].[hash].css' : '[name].css' } }, { loader: 'extract-loader' @@ -55,10 +67,35 @@ module.exports = { } }] }, + { + test: /\.json$/, + include: /src/, + type: 'javascript/auto', + loader: 'file-loader', + options: { + name: PRODUCTION ? '[name].[hash].json' : '[name].json' + } + }, + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader', + options: { + cacheDirectory: true + } + }, { test: /\.jsx$/, exclude: /node_modules/, - loader: 'babel-loader' + loader: 'babel-loader', + options: { + cacheDirectory: true, + plugins: [ + ['@babel/plugin-transform-react-jsx', { + pragma: 'createElement' + }] + ] + } }, { test: /\.(graphql|gql)$/, @@ -70,7 +107,7 @@ module.exports = { use: [{ loader: 'file-loader', options: { - name: '[name].[ext]' + name: PRODUCTION ? '[name].[hash].[ext]' : '[name].[ext]' } }] }, diff --git a/webpack.web.babel.js b/webpack.web.babel.js deleted file mode 100644 index 97793fcc..00000000 --- a/webpack.web.babel.js +++ /dev/null @@ -1,82 +0,0 @@ -const webpack = require('webpack'); -const merge = require('webpack-merge'); -const common = require('./webpack.web.common.js'); -const path = require('path'); - -const CleanPlugin = require('clean-webpack-plugin'); -const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); -const ManifestPlugin = require('webpack-manifest-plugin'); - -const commit_hash = require('child_process').execSync('git rev-parse HEAD').toString().trim(); - -/* global module __dirname */ - -const config = module.exports = merge(common, { - devtool: 'source-map', - - module: { - rules: [{ - test: /\.jsx?$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - plugins: ['transform-es2015-classes'] - } - } - }] - }, - - plugins: [ - new CleanPlugin(['dist/babel']), - new UglifyJSPlugin({ - sourceMap: true, - uglifyOptions: { - compress: { - keep_fnames: true, - keep_classnames: true - }, - mangle: { - keep_classnames: true, - keep_fnames: true - } - } - }), - new webpack.DefinePlugin({ - __git_commit__: JSON.stringify(commit_hash) - }), - new ManifestPlugin({ - basePath: 'babel/', - publicPath: 'babel/', - map: data => { - if ( data.name.endsWith('.scss') ) - data.name = `${data.name.substr(0,data.name.length - 5)}.css`; - - return data; - } - }) - ], - - output: { - publicPath: '//cdn.frankerfacez.com/static/babel/', - path: path.resolve(__dirname, 'dist/babel'), - filename: '[name].[hash].js' - } -}); - - -// This is why we can't have nice things. -// Why can't I just access process.env.NODE_ENV from -// one of these files when I set it with webpack's -// CLI? So stupid. -// -// So here we go. -// This is crap. -// But it works. - -for(const rule of config.module.rules) { - if ( Array.isArray(rule.use) ) - for(const use of rule.use) - if ( use.options && use.options.name && use.options.name.startsWith('[name].') ) - use.options.name = `[name].[hash].${use.options.name.slice(7)}`; -} \ No newline at end of file diff --git a/webpack.web.dev.babel.js b/webpack.web.dev.babel.js deleted file mode 100644 index d664bb9e..00000000 --- a/webpack.web.dev.babel.js +++ /dev/null @@ -1,40 +0,0 @@ -/* eslint-disable */ -const path = require('path'); -const merge = require('webpack-merge'); -const dev = require('./webpack.web.dev.js'); - -const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); - -/* global module */ - -module.exports = merge(dev, { - module: { - rules: [{ - test: /\.jsx?$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - cacheDirectory: true, - plugins: ['transform-es2015-classes'] - } - } - }] - }, - - plugins: [ - new UglifyJSPlugin({ - sourceMap: true, - uglifyOptions: { - compress: { - keep_fnames: true, - keep_classnames: true - }, - mangle: { - keep_classnames: true, - keep_fnames: true - } - } - }) - ] -}); \ No newline at end of file diff --git a/webpack.web.dev.js b/webpack.web.dev.js index 59945103..0314b1fc 100644 --- a/webpack.web.dev.js +++ b/webpack.web.dev.js @@ -9,6 +9,7 @@ const webpack = require('webpack'); /* global module */ module.exports = merge(common, { + mode: 'development', devtool: 'inline-source-map', plugins: [ @@ -39,7 +40,7 @@ module.exports = merge(common, { proxy: { '**': { - target: 'http://cdn.frankerfacez.com/', + target: 'https://cdn.frankerfacez.com/', changeOrigin: true } }, @@ -63,6 +64,7 @@ module.exports = merge(common, { output: { publicPath: '//localhost:8000/script/', filename: '[name].js', - jsonpFunction: 'ffzWebpackJsonp' + jsonpFunction: 'ffzWebpackJsonp', + crossOriginLoading: 'anonymous' } }) \ No newline at end of file diff --git a/webpack.web.dev.prod.js b/webpack.web.dev.prod.js new file mode 100644 index 00000000..884d3e1e --- /dev/null +++ b/webpack.web.dev.prod.js @@ -0,0 +1,67 @@ +/* eslint-disable */ +const path = require('path'); +const merge = require('webpack-merge'); +const prod = require('./webpack.web.prod.js'); + +const CopyPlugin = require('copy-webpack-plugin'); +const webpack = require('webpack'); + +/* global module */ + +module.exports = merge(prod, { + plugins: [ + new CopyPlugin([ + { + from: './src/entry.js', + to: 'script.js' + } + ]), + new webpack.DefinePlugin({ + __git_commit__: null + }) + ], + + devServer: { + https: true, + port: 8000, + compress: true, + inline: false, + + allowedHosts: [ + '.twitch.tv', + '.frankerfacez.com' + ], + + contentBase: path.join(__dirname, 'dev_cdn'), + publicPath: '/script/', + + proxy: { + '**': { + target: 'https://cdn.frankerfacez.com/', + changeOrigin: true + } + }, + + before(app) { + // Because the headers config option is broken. + app.get('/*', (req, res, next) => { + res.setHeader('Access-Control-Allow-Origin', '*'); + next(); + }); + + app.get('/dev_server', (req, res) => { + res.json({ + path: process.cwd(), + version: 2 + }) + }); + } + }, + + output: { + publicPath: '//localhost:8000/script/', + filename: '[name].js', + jsonpFunction: 'ffzWebpackJsonp', + crossOriginLoading: 'anonymous' + } +}) \ No newline at end of file diff --git a/webpack.web.prod.js b/webpack.web.prod.js index b941028d..65ff5c80 100644 --- a/webpack.web.prod.js +++ b/webpack.web.prod.js @@ -3,11 +3,11 @@ const merge = require('webpack-merge'); const common = require('./webpack.web.common.js'); const CopyPlugin = require('copy-webpack-plugin'); -const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); -const CleanPlugin = require('clean-webpack-plugin'); +const {CleanWebpackPlugin} = require('clean-webpack-plugin'); -const uglify = require('uglify-es'); +const Terser = require('terser'); // Get Git info @@ -15,24 +15,25 @@ const commit_hash = require('child_process').execSync('git rev-parse HEAD').toSt /* global module Buffer */ -const config = module.exports = merge(common, { +module.exports = merge(common, { + mode: 'production', devtool: 'source-map', - plugins: [ - new CleanPlugin(['dist']), - new UglifyJSPlugin({ - sourceMap: true, - uglifyOptions: { - compress: { - keep_fnames: true, - keep_classnames: true - }, - mangle: { + optimization: { + concatenateModules: false, + minimizer: [ + new TerserPlugin({ + sourceMap: true, + terserOptions: { keep_classnames: true, keep_fnames: true } - } - }), + }) + ] + }, + + plugins: [ + new CleanWebpackPlugin(), new webpack.DefinePlugin({ __git_commit__: JSON.stringify(commit_hash) }), @@ -42,7 +43,7 @@ const config = module.exports = merge(common, { to: 'script.min.js', transform: content => { const text = content.toString('utf8'); - const minified = uglify.minify(text); + const minified = Terser.minify(text); return (minified && minified.code) ? Buffer.from(minified.code) : content; } } @@ -61,21 +62,4 @@ const config = module.exports = merge(common, { publicPath: '//cdn.frankerfacez.com/static/', filename: '[name].[hash].js' } -}); - - -// This is why we can't have nice things. -// Why can't I just access process.env.NODE_ENV from -// one of these files when I set it with webpack's -// CLI? So stupid. -// -// So here we go. -// This is crap. -// But it works. - -for(const rule of config.module.rules) { - if ( Array.isArray(rule.use) ) - for(const use of rule.use) - if ( use.options && use.options.name && use.options.name.startsWith('[name].') ) - use.options.name = `[name].[hash].${use.options.name.slice(7)}`; -} \ No newline at end of file +}); \ No newline at end of file