diff --git a/js/package.json b/js/package.json index 9a38e454c..6507a28d0 100644 --- a/js/package.json +++ b/js/package.json @@ -27,16 +27,16 @@ ], "scripts": { "build": "npm run build:lib && npm run build:app", - "build:app": "webpack --config webpack/app", - "build:lib": "webpack --config webpack/libraries", + "build:app": "parallel-webpack -p=2 --config webpack/app", + "build:lib": "parallel-webpack -p=2 --config webpack/libraries", "build:markdown": "babel-node ./scripts/build-rpc-markdown.js", "build:json": "babel-node ./scripts/build-rpc-json.js", "build:embed": "EMBED=1 node webpack/embed", "build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js", "ci:build": "npm run ci:build:lib && npm run ci:build:app && npm run ci:build:embed", - "ci:build:app": "NODE_ENV=production webpack --config webpack/app", - "ci:build:lib": "NODE_ENV=production webpack --config webpack/libraries", - "ci:build:npm": "NODE_ENV=production webpack --config webpack/npm", + "ci:build:app": "NODE_ENV=production parallel-webpack -p=2 --config webpack/app", + "ci:build:lib": "NODE_ENV=production parallel-webpack -p=2 --config webpack/libraries", + "ci:build:npm": "NODE_ENV=production parallel-webpack -p=2 --config webpack/npm", "ci:build:jsonrpc": "babel-node ./scripts/build-rpc-json.js --output .npmjs/jsonrpc", "ci:build:embed": "NODE_ENV=production EMBED=1 node webpack/embed", "clean": "rm -rf ./.build ./.coverage ./.happypack ./build ./node_modules/.cache", diff --git a/js/webpack/app.js b/js/webpack/app.js index edf9843eb..c169c348d 100644 --- a/js/webpack/app.js +++ b/js/webpack/app.js @@ -49,218 +49,224 @@ const entry = isEmbed index: './index.js' }); -module.exports = { - cache: !isProd, - devtool: isProd ? '#hidden-source-map' : '#source-map', +module.exports = Object.keys(entry).map((entryName) => { + const entrySrc = entry[entryName]; - context: path.join(__dirname, '../src'), - entry, - output: { - path: path.join(__dirname, '../', DEST), - filename: '[name].js' - }, + return { + cache: !isProd, + devtool: isProd ? '#hidden-source-map' : '#source-map', - module: { - rules: [ - rulesParity, - rulesEs6, - { - test: /\.js$/, - exclude: /(node_modules)/, - use: [ 'babel-loader' ] - }, - { - test: /\.json$/, - use: [ 'json-loader' ] - }, - { - test: /\.ejs$/, - use: [ 'ejs-loader' ] - }, - { - test: /\.html$/, - use: [ - { + context: path.join(__dirname, '../src'), + entry: { + [entryName]: entrySrc + }, + output: { + path: path.join(__dirname, '../', DEST), + filename: '[name].js' + }, + + module: { + rules: [ + rulesParity, + rulesEs6, + { + test: /\.js$/, + exclude: /(node_modules)/, + use: [ 'babel-loader' ] + }, + { + test: /\.json$/, + use: [ 'json-loader' ] + }, + { + test: /\.ejs$/, + use: [ 'ejs-loader' ] + }, + { + test: /\.html$/, + use: [ + { + loader: 'file-loader', + options: { + name: '[name].[ext]' + } + }, + 'extract-loader', + { + loader: 'html-loader', + options: { + root: path.resolve(__dirname, '../assets/images'), + attrs: ['img:src', 'link:href'] + } + } + ] + }, + { + test: /\.md$/, + use: [ 'html-loader', 'markdown-loader' ] + }, + { + test: /\.css$/, + include: /node_modules\/(?!@parity)*/, + use: [ 'style-loader', 'css-loader' ] + }, + { + test: /\.css$/, + exclude: /node_modules\/(?!@parity)*/, + use: [ + 'style-loader', + { + loader: 'css-loader', + options: { + importLoaders: 1, + localIdentName: '[name]_[local]_[hash:base64:10]', + minimize: true, + modules: true + } + }, + { + loader: 'postcss-loader', + options: { + plugins: (loader) => [ + require('postcss-import'), + require('postcss-nested'), + require('postcss-simple-vars') + ] + } + } + ] + }, + { + test: /\.(png|jpg)$/, + use: [ { loader: 'file-loader', options: { - name: '[name].[ext]' + name: 'assets/[name].[hash].[ext]' } - }, - 'extract-loader', - { - loader: 'html-loader', + } ] + }, + { + test: /\.(woff|woff2|ttf|eot|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/, + use: [ { + loader: 'file-loader', options: { - root: path.resolve(__dirname, '../assets/images'), - attrs: ['img:src', 'link:href'] + name: 'fonts/[name][hash].[ext]' } - } - ] - }, - { - test: /\.md$/, - use: [ 'html-loader', 'markdown-loader' ] - }, - { - test: /\.css$/, - include: /node_modules\/(?!@parity)*/, - use: [ 'style-loader', 'css-loader' ] - }, - { - test: /\.css$/, - exclude: /node_modules\/(?!@parity)*/, - use: [ - 'style-loader', - { - loader: 'css-loader', + } ] + }, + { + test: /parity-logo-white-no-text\.svg/, + use: [ 'url-loader' ] + }, + { + test: /\.svg(\?v=[0-9]\.[0-9]\.[0-9])?$/, + exclude: [ /parity-logo-white-no-text\.svg/ ], + use: [ { + loader: 'file-loader', options: { - importLoaders: 1, - localIdentName: '[name]_[local]_[hash:base64:10]', - minimize: true, - modules: true + name: 'assets/[name].[hash].[ext]' } - }, - { - loader: 'postcss-loader', - options: { - plugins: (loader) => [ - require('postcss-import'), - require('postcss-nested'), - require('postcss-simple-vars') - ] - } - } - ] - }, - { - test: /\.(png|jpg)$/, - use: [ { - loader: 'file-loader', - options: { - name: 'assets/[name].[hash].[ext]' - } - } ] - }, - { - test: /\.(woff|woff2|ttf|eot|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/, - use: [ { - loader: 'file-loader', - options: { - name: 'fonts/[name][hash].[ext]' - } - } ] - }, - { - test: /parity-logo-white-no-text\.svg/, - use: [ 'url-loader' ] - }, - { - test: /\.svg(\?v=[0-9]\.[0-9]\.[0-9])?$/, - exclude: [ /parity-logo-white-no-text\.svg/ ], - use: [ { - loader: 'file-loader', - options: { - name: 'assets/[name].[hash].[ext]' - } - } ] - } - ], - noParse: [ - /node_modules\/sinon/ - ] - }, - - resolve: { - alias: { - '~': path.resolve(__dirname, '..'), - '@parity/abi': path.resolve(__dirname, '../node_modules/@parity/abi'), - '@parity/api': path.resolve(__dirname, '../node_modules/@parity/api'), - '@parity/etherscan': path.resolve(__dirname, '../node_modules/@parity/etherscan'), - '@parity/jsonrpc': path.resolve(__dirname, '../node_modules/@parity/jsonrpc'), - '@parity/parity.js': path.resolve(__dirname, '../node_modules/@parity/parity.js'), - '@parity/shared': path.resolve(__dirname, '../node_modules/@parity/shared'), - '@parity/ui': path.resolve(__dirname, '../node_modules/@parity/ui'), - '@parity/wordlist': path.resolve(__dirname, '../node_modules/@parity/wordlist'), - '@parity': path.resolve(__dirname, '../packages') + } ] + } + ], + noParse: [ + /node_modules\/sinon/ + ] }, - modules: [ - path.join(__dirname, '../node_modules') - ], - extensions: ['.json', '.js', '.jsx'], - unsafeCache: true - }, - node: { - fs: 'empty' - }, + resolve: { + alias: { + '~': path.resolve(__dirname, '..'), + '@parity/abi': path.resolve(__dirname, '../node_modules/@parity/abi'), + '@parity/api': path.resolve(__dirname, '../node_modules/@parity/api'), + '@parity/etherscan': path.resolve(__dirname, '../node_modules/@parity/etherscan'), + '@parity/jsonrpc': path.resolve(__dirname, '../node_modules/@parity/jsonrpc'), + '@parity/parity.js': path.resolve(__dirname, '../node_modules/@parity/parity.js'), + '@parity/shared': path.resolve(__dirname, '../node_modules/@parity/shared'), + '@parity/ui': path.resolve(__dirname, '../node_modules/@parity/ui'), + '@parity/wordlist': path.resolve(__dirname, '../node_modules/@parity/wordlist'), + '@parity': path.resolve(__dirname, '../packages') + }, + modules: [ + path.join(__dirname, '../node_modules') + ], + extensions: ['.json', '.js', '.jsx'], + unsafeCache: true + }, - plugins: (function () { - const DappsHTMLInjection = [] - .concat(DAPPS_BUILTIN, DAPPS_VIEWS) - .filter((dapp) => !dapp.skipBuild) - .map((dapp) => { - return new HtmlWebpackPlugin({ - title: dapp.name, - filename: dapp.url + '.html', - template: '../packages/dapps/index.ejs', - favicon: FAVICON, - secure: dapp.secure, - chunks: [ dapp.url ] + node: { + fs: 'empty' + }, + + plugins: (function () { + const DappsHTMLInjection = [] + .concat(DAPPS_BUILTIN, DAPPS_VIEWS) + .filter((dapp) => !dapp.skipBuild) + .map((dapp) => { + return new HtmlWebpackPlugin({ + title: dapp.name, + filename: dapp.url + '.html', + template: '../packages/dapps/index.ejs', + favicon: FAVICON, + secure: dapp.secure, + chunks: [ dapp.url ] + }); }); - }); - let plugins = Shared.getPlugins().concat( - new WebpackErrorNotificationPlugin() - ); - - if (!isEmbed) { - plugins = [].concat( - plugins, - - new HtmlWebpackPlugin({ - title: 'Parity', - filename: 'index.html', - template: './index.ejs', - favicon: FAVICON, - chunks: [ 'index' ] - }), - - new ServiceWorkerWebpackPlugin({ - entry: path.join(__dirname, '../src/serviceWorker.js') - }), - - DappsHTMLInjection, - - new CopyWebpackPlugin([ - { from: './error_pages.css', to: 'styles.css' }, - { from: '../packages/dapps/static' } - ], {}) + let plugins = Shared.getPlugins().concat( + new WebpackErrorNotificationPlugin() ); - } - if (isEmbed) { - plugins.push( - new HtmlWebpackPlugin({ - title: 'Parity Bar', - filename: 'embed.html', - template: './index.ejs', - favicon: FAVICON, - chunks: [ 'embed' ] - }) - ); - } + if (!isEmbed) { + plugins = [].concat( + plugins, - // if (!isAnalize && !isProd) { - // const DEST_I18N = path.join(__dirname, '..', DEST, 'i18n'); - // - // plugins.push( - // new ReactIntlAggregatePlugin({ - // messagesPattern: DEST_I18N + '/i18n/**/*.json', - // aggregateOutputDir: DEST_I18N + '/i18n/', - // aggregateFilename: 'en' - // }) - // ); - // } + new HtmlWebpackPlugin({ + title: 'Parity', + filename: 'index.html', + template: './index.ejs', + favicon: FAVICON, + chunks: [ 'index' ] + }), - return plugins; - }()) -}; + new ServiceWorkerWebpackPlugin({ + entry: path.join(__dirname, '../src/serviceWorker.js') + }), + + DappsHTMLInjection, + + new CopyWebpackPlugin([ + { from: './error_pages.css', to: 'styles.css' }, + { from: '../packages/dapps/static' } + ], {}) + ); + } + + if (isEmbed) { + plugins.push( + new HtmlWebpackPlugin({ + title: 'Parity Bar', + filename: 'embed.html', + template: './index.ejs', + favicon: FAVICON, + chunks: [ 'embed' ] + }) + ); + } + + // if (!isAnalize && !isProd) { + // const DEST_I18N = path.join(__dirname, '..', DEST, 'i18n'); + // + // plugins.push( + // new ReactIntlAggregatePlugin({ + // messagesPattern: DEST_I18N + '/i18n/**/*.json', + // aggregateOutputDir: DEST_I18N + '/i18n/', + // aggregateFilename: 'en' + // }) + // ); + // } + + return plugins; + }()) + }; +}); diff --git a/js/webpack/libraries.js b/js/webpack/libraries.js index db46f14bf..4297fd068 100644 --- a/js/webpack/libraries.js +++ b/js/webpack/libraries.js @@ -24,61 +24,61 @@ const Shared = require('./shared'); const DEST = process.env.BUILD_DEST || '.build'; -module.exports = { - context: path.join(__dirname, '../src'), - entry: { - inject: ['./inject.js'], - parity: ['./inject.js'], - web3: ['./inject.js'] - }, - output: { - path: path.join(__dirname, '../', DEST), - filename: '[name].js', - library: '[name].js', - libraryTarget: 'umd' - }, +module.exports = ['inject', 'parity', 'web3'].map((entryName) => { + return { + context: path.join(__dirname, '../src'), + entry: { + [entryName]: ['./inject.js'] + }, + output: { + path: path.join(__dirname, '../', DEST), + filename: '[name].js', + library: '[name].js', + libraryTarget: 'umd' + }, - resolve: { - alias: { - '~': path.resolve(__dirname, '..'), - '@parity/abi': path.resolve(__dirname, '../node_modules/@parity/abi'), - '@parity/api': path.resolve(__dirname, '../node_modules/@parity/api'), - '@parity/etherscan': path.resolve(__dirname, '../node_modules/@parity/etherscan'), - '@parity/jsonrpc': path.resolve(__dirname, '../node_modules/@parity/jsonrpc'), - '@parity/shared': path.resolve(__dirname, '../node_modules/@parity/shared'), - '@parity/ui': path.resolve(__dirname, '../node_modules/@parity/ui'), - '@parity/wordlist': path.resolve(__dirname, '../node_modules/@parity/wordlist'), - '@parity': path.resolve(__dirname, '../packages') - } - }, - - node: { - fs: 'empty' - }, - - module: { - rules: [ - rulesParity, - rulesEs6, - { - test: /\.js$/, - exclude: /node_modules/, - use: [ 'babel-loader' ] - }, - { - test: /\.json$/, - use: [ 'json-loader' ] - }, - { - test: /\.html$/, - use: [ { - loader: 'file-loader', - options: { - name: '[name].[ext]' - } - } ] + resolve: { + alias: { + '~': path.resolve(__dirname, '..'), + '@parity/abi': path.resolve(__dirname, '../node_modules/@parity/abi'), + '@parity/api': path.resolve(__dirname, '../node_modules/@parity/api'), + '@parity/etherscan': path.resolve(__dirname, '../node_modules/@parity/etherscan'), + '@parity/jsonrpc': path.resolve(__dirname, '../node_modules/@parity/jsonrpc'), + '@parity/shared': path.resolve(__dirname, '../node_modules/@parity/shared'), + '@parity/ui': path.resolve(__dirname, '../node_modules/@parity/ui'), + '@parity/wordlist': path.resolve(__dirname, '../node_modules/@parity/wordlist'), + '@parity': path.resolve(__dirname, '../packages') } - ] - }, - plugins: Shared.getPlugins() -}; + }, + + node: { + fs: 'empty' + }, + + module: { + rules: [ + rulesParity, + rulesEs6, + { + test: /\.js$/, + exclude: /node_modules/, + use: [ 'babel-loader' ] + }, + { + test: /\.json$/, + use: [ 'json-loader' ] + }, + { + test: /\.html$/, + use: [ { + loader: 'file-loader', + options: { + name: '[name].[ext]' + } + } ] + } + ] + }, + plugins: Shared.getPlugins() + }; +});