From b1b02d0e3282c73823b9071d5ba880fb1cf6edec Mon Sep 17 00:00:00 2001 From: syuilo <syuilotan@yahoo.co.jp> Date: Mon, 12 Nov 2018 04:09:02 +0900 Subject: [PATCH] [Client] Enable code splitting And some optimizations --- gulpfile.ts | 11 +- package.json | 2 + src/client/app/common/scripts/get-md5.ts | 14 +- .../app/common/views/components/emoji.vue | 11 +- .../common/views/directives/autocomplete.ts | 5 +- .../desktop/views/components/game-window.vue | 2 +- .../app/desktop/views/pages/games/reversi.vue | 2 +- .../app/mobile/views/pages/games/reversi.vue | 2 +- src/client/app/tsconfig.json | 2 +- webpack.config.ts | 146 +++++++----------- 10 files changed, 82 insertions(+), 115 deletions(-) diff --git a/gulpfile.ts b/gulpfile.ts index 029979c35..2b420f5fe 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -57,16 +57,7 @@ gulp.task('build:copy:views', () => gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views')) ); -// 互換性のため -gulp.task('build:copy:lang', () => - gulp.src(['./built/client/assets/*.*-*.js']) - .pipe(rename(path => { - path.basename = path.basename.replace(/\-(.*)$/, ''); - })) - .pipe(gulp.dest('./built/client/assets/')) -); - -gulp.task('build:copy', ['build:copy:views', 'build:copy:lang'], () => +gulp.task('build:copy', ['build:copy:views'], () => gulp.src([ './build/Release/crypto_key.node', './src/const.json', diff --git a/package.json b/package.json index 68cdf98d1..19b04debf 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "commander": "2.19.0", "crc-32": "1.2.0", "css-loader": "1.0.1", + "cssnano": "4.1.7", "dateformat": "3.0.3", "debug": "4.1.0", "deep-equal": "1.0.1", @@ -167,6 +168,7 @@ "os-utils": "0.0.14", "parse5": "5.1.0", "portscanner": "2.2.0", + "postcss-loader": "3.0.0", "progress-bar-webpack-plugin": "1.11.0", "promise-limit": "2.7.0", "promise-sequential": "1.1.1", diff --git a/src/client/app/common/scripts/get-md5.ts b/src/client/app/common/scripts/get-md5.ts index 24ac04c1a..51a45b30d 100644 --- a/src/client/app/common/scripts/get-md5.ts +++ b/src/client/app/common/scripts/get-md5.ts @@ -1,8 +1,10 @@ -const crypto = require('crypto'); +// スクリプトサイズがデカい +//const crypto = require('crypto'); export default (data: ArrayBuffer) => { - const buf = new Buffer(data); - const hash = crypto.createHash("md5"); - hash.update(buf); - return hash.digest("hex"); -}; \ No newline at end of file + //const buf = new Buffer(data); + //const hash = crypto.createHash("md5"); + //hash.update(buf); + //return hash.digest("hex"); + return ''; +}; diff --git a/src/client/app/common/views/components/emoji.vue b/src/client/app/common/views/components/emoji.vue index 2fb7055f0..c57d6a944 100644 --- a/src/client/app/common/views/components/emoji.vue +++ b/src/client/app/common/views/components/emoji.vue @@ -7,7 +7,8 @@ <script lang="ts"> import Vue from 'vue'; -import { lib } from 'emojilib'; +// スクリプトサイズがデカい +//import { lib } from 'emojilib'; export default Vue.extend({ props: { @@ -50,10 +51,10 @@ export default Vue.extend({ this.customEmoji = customEmoji; this.url = customEmoji.url; } else { - const emoji = lib[this.name]; - if (emoji) { - this.char = emoji.char; - } + //const emoji = lib[this.name]; + //if (emoji) { + // this.char = emoji.char; + //} } } else { this.char = this.emoji; diff --git a/src/client/app/common/views/directives/autocomplete.ts b/src/client/app/common/views/directives/autocomplete.ts index 069aeb278..4440747e1 100644 --- a/src/client/app/common/views/directives/autocomplete.ts +++ b/src/client/app/common/views/directives/autocomplete.ts @@ -1,5 +1,4 @@ import * as getCaretCoordinates from 'textarea-caret'; -import MkAutocomplete from '../components/autocomplete.vue'; import { toASCII } from 'punycode'; export default { @@ -123,7 +122,7 @@ class Autocomplete { /** * サジェストを提示します。 */ - private open(type, q) { + private async open(type, q) { if (type != this.currentType) { this.close(); } @@ -143,6 +142,8 @@ class Autocomplete { this.suggestion.y = y; this.suggestion.q = q; } else { + const MkAutocomplete = await import('../components/autocomplete.vue').then(m => m.default); + // サジェスト要素作成 this.suggestion = new MkAutocomplete({ parent: this.vm, diff --git a/src/client/app/desktop/views/components/game-window.vue b/src/client/app/desktop/views/components/game-window.vue index 2ffe8d2f9..10db06236 100644 --- a/src/client/app/desktop/views/components/game-window.vue +++ b/src/client/app/desktop/views/components/game-window.vue @@ -13,7 +13,7 @@ import { url } from '../../../config'; export default Vue.extend({ i18n: i18n('desktop/views/components/game-window.vue'), components: { - XReversi: () => import('../../../common/views/components/games/reversi/reversi.vue') + XReversi: () => import('../../../common/views/components/games/reversi/reversi.vue').then(m => m.default) }, data() { return { diff --git a/src/client/app/desktop/views/pages/games/reversi.vue b/src/client/app/desktop/views/pages/games/reversi.vue index ecf138bdd..d281e0b67 100644 --- a/src/client/app/desktop/views/pages/games/reversi.vue +++ b/src/client/app/desktop/views/pages/games/reversi.vue @@ -9,7 +9,7 @@ import Vue from 'vue'; export default Vue.extend({ components: { - XReversi: () => import('../../../../common/views/components/games/reversi/reversi.vue') + XReversi: () => import('../../../../common/views/components/games/reversi/reversi.vue').then(m => m.default) }, props: { ui: { diff --git a/src/client/app/mobile/views/pages/games/reversi.vue b/src/client/app/mobile/views/pages/games/reversi.vue index 470f5cb16..983fb0782 100644 --- a/src/client/app/mobile/views/pages/games/reversi.vue +++ b/src/client/app/mobile/views/pages/games/reversi.vue @@ -12,7 +12,7 @@ import i18n from '../../../../i18n'; export default Vue.extend({ i18n: i18n('mobile/views/pages/games/reversi.vue'), components: { - XReversi: () => import('../../../../common/views/components/games/reversi/reversi.vue') + XReversi: () => import('../../../../common/views/components/games/reversi/reversi.vue').then(m => m.default) }, mounted() { document.title = `${this.$root.instanceName} %i18n:@reversi%`; diff --git a/src/client/app/tsconfig.json b/src/client/app/tsconfig.json index 4a0546967..8605da75a 100644 --- a/src/client/app/tsconfig.json +++ b/src/client/app/tsconfig.json @@ -10,7 +10,7 @@ "declaration": false, "sourceMap": false, "target": "es2017", - "module": "commonjs", + "module": "esnext", "removeComments": false, "noLib": false, "strict": true, diff --git a/webpack.config.ts b/webpack.config.ts index ee1b59c95..d924d2b5f 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -17,82 +17,28 @@ const meta = require('./package.json'); const version = meta.clientVersion; const codename = meta.codename; -const langs = Object.keys(locales); - const isProduction = process.env.NODE_ENV == 'production'; -// Entries -const entry = { - desktop: './src/client/app/desktop/script.ts', - mobile: './src/client/app/mobile/script.ts', - dev: './src/client/app/dev/script.ts', - auth: './src/client/app/auth/script.ts', - admin: './src/client/app/admin/script.ts', - sw: './src/client/app/sw.js' +const postcss = { + loader: 'postcss-loader', + options: { + plugins: [ + require('cssnano')({ + preset: 'default' + }) + ] + }, }; -const output = { - path: __dirname + '/built/client/assets', - filename: `[name].${version}.-.js` -}; - -//#region Define consts -const consts = { - _THEME_COLOR_: constants.themeColor, - _COPYRIGHT_: constants.copyright, - _VERSION_: meta.version, - _CLIENT_VERSION_: version, - _CODENAME_: codename, - _LANG_: '%lang%', - _LANGS_: Object.keys(locales).map(l => [l, locales[l].meta.lang]), - _LOCALE_: '%locale%', - _ENV_: process.env.NODE_ENV -}; - -const _consts: { [ key: string ]: any } = {}; - -Object.keys(consts).forEach(key => { - _consts[key] = JSON.stringify((consts as any)[key]); -}); -//#endregion - -const plugins = [ - //new HardSourceWebpackPlugin(), - new ProgressBarPlugin({ - format: chalk` {cyan.bold yes we can} {bold [}:bar{bold ]} {green.bold :percent} {gray (:current/:total)} :elapseds`, - clear: false - }), - new webpack.DefinePlugin(_consts), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development') - }), - new WebpackOnBuildPlugin((stats: any) => { - fs.writeFileSync('./built/client/meta.json', JSON.stringify({ - version - }), 'utf-8'); - - //#region i18n - langs.forEach(lang => { - Object.keys(entry).forEach(file => { - let src = fs.readFileSync(`${__dirname}/built/client/assets/${file}.${version}.-.js`, 'utf-8'); - - src = src.replace('%lang%', lang); - src = src.replace('"%locale%"', JSON.stringify(locales[lang])); - - fs.writeFileSync(`${__dirname}/built/client/assets/${file}.${version}.${lang}.js`, src, 'utf-8'); - }); - }); - //#endregion - }), - new VueLoaderPlugin() -]; - -if (isProduction) { - plugins.push(new webpack.optimize.ModuleConcatenationPlugin()); -} - -module.exports = { - entry, +module.exports = Object.keys(locales).map(lang => ({ + entry: { + desktop: './src/client/app/desktop/script.ts', + mobile: './src/client/app/mobile/script.ts', + dev: './src/client/app/dev/script.ts', + auth: './src/client/app/auth/script.ts', + admin: './src/client/app/admin/script.ts', + sw: './src/client/app/sw.js' + }, module: { rules: [{ test: /\.vue$/, @@ -118,21 +64,17 @@ module.exports = { }, { loader: 'css-loader', options: { - modules: true, - minimize: true + modules: true } - }, { + }, postcss, { loader: 'stylus-loader' }] }, { use: [{ loader: 'vue-style-loader' }, { - loader: 'css-loader', - options: { - minimize: true - } - }, { + loader: 'css-loader' + }, postcss, { loader: 'stylus-loader' }] }] @@ -141,11 +83,8 @@ module.exports = { use: [{ loader: 'vue-style-loader' }, { - loader: 'css-loader', - options: { - minimize: true - } - }] + loader: 'css-loader' + }, postcss] }, { test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/, loader: 'url-loader' @@ -165,8 +104,39 @@ module.exports = { }] }] }, - plugins, - output, + plugins: [ + //new HardSourceWebpackPlugin(), + new ProgressBarPlugin({ + format: chalk` {cyan.bold yes we can} {bold [}:bar{bold ]} {green.bold :percent} {gray (:current/:total)} :elapseds`, + clear: false + }), + new webpack.DefinePlugin({ + _THEME_COLOR_: JSON.stringify(constants.themeColor), + _COPYRIGHT_: JSON.stringify(constants.copyright), + _VERSION_: JSON.stringify(meta.version), + _CLIENT_VERSION_: JSON.stringify(version), + _CODENAME_: JSON.stringify(codename), + _LANG_: JSON.stringify(lang), + _LANGS_: JSON.stringify(Object.keys(locales).map(l => [l, locales[l].meta.lang])), + _LOCALE_: JSON.stringify(locales[lang]), + _ENV_: JSON.stringify(process.env.NODE_ENV) + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development') + }), + new WebpackOnBuildPlugin((stats: any) => { + fs.writeFileSync('./built/client/meta.json', JSON.stringify({ + version + }), 'utf-8'); + }), + new VueLoaderPlugin(), + new webpack.optimize.ModuleConcatenationPlugin() + ], + output: { + path: __dirname + '/built/client/assets', + filename: `[name].${version}.${lang}.js`, + publicPath: `/assets/` + }, resolve: { extensions: [ '.js', '.ts', '.json' @@ -181,4 +151,4 @@ module.exports = { cache: true, devtool: false, //'source-map', mode: isProduction ? 'production' : 'development' -}; +}));