@@ -69,7 +69,7 @@ COPY Gemfile Gemfile.lock package.json yarn.lock .yarnclean /mastodon/ | |||||
RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \ | RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \ | ||||
&& bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \ | && bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \ | ||||
&& yarn --pure-lockfile \ | |||||
&& yarn install --pure-lockfile --ignore-engines \ | |||||
&& yarn cache clean | && yarn cache clean | ||||
RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \ | RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \ | ||||
@@ -0,0 +1,8 @@ | |||||
import Rails from 'rails-ujs'; | |||||
export function start() { | |||||
require('font-awesome/css/font-awesome.css'); | |||||
require.context('../images/', true); | |||||
Rails.start(); | |||||
}; |
@@ -1,4 +1,7 @@ | |||||
import loadPolyfills from '../mastodon/load_polyfills'; | import loadPolyfills from '../mastodon/load_polyfills'; | ||||
import { start } from '../mastodon/common'; | |||||
start(); | |||||
function loaded() { | function loaded() { | ||||
const TimelineContainer = require('../mastodon/containers/timeline_container').default; | const TimelineContainer = require('../mastodon/containers/timeline_container').default; | ||||
@@ -1,4 +1,7 @@ | |||||
import { delegate } from 'rails-ujs'; | import { delegate } from 'rails-ujs'; | ||||
import { start } from '../mastodon/common'; | |||||
start(); | |||||
function handleDeleteStatus(event) { | function handleDeleteStatus(event) { | ||||
const [data] = event.detail; | const [data] = event.detail; | ||||
@@ -1,4 +1,7 @@ | |||||
import loadPolyfills from '../mastodon/load_polyfills'; | import loadPolyfills from '../mastodon/load_polyfills'; | ||||
import { start } from '../mastodon/common'; | |||||
start(); | |||||
loadPolyfills().then(() => { | loadPolyfills().then(() => { | ||||
require('../mastodon/main').default(); | require('../mastodon/main').default(); | ||||
@@ -1,6 +0,0 @@ | |||||
import { start } from 'rails-ujs'; | |||||
import 'font-awesome/css/font-awesome.css'; | |||||
require.context('../images/', true); | |||||
start(); |
@@ -1,5 +1,8 @@ | |||||
import loadPolyfills from '../mastodon/load_polyfills'; | import loadPolyfills from '../mastodon/load_polyfills'; | ||||
import ready from '../mastodon/ready'; | import ready from '../mastodon/ready'; | ||||
import { start } from '../mastodon/common'; | |||||
start(); | |||||
window.addEventListener('message', e => { | window.addEventListener('message', e => { | ||||
const data = e.data || {}; | const data = e.data || {}; | ||||
@@ -1,4 +1,7 @@ | |||||
import loadPolyfills from '../mastodon/load_polyfills'; | import loadPolyfills from '../mastodon/load_polyfills'; | ||||
import { start } from '../mastodon/common'; | |||||
start(); | |||||
function loaded() { | function loaded() { | ||||
const ComposeContainer = require('../mastodon/containers/compose_container').default; | const ComposeContainer = require('../mastodon/containers/compose_container').default; | ||||
@@ -16,6 +16,8 @@ if (process.env.VAGRANT) { | |||||
} | } | ||||
module.exports = merge(sharedConfig, { | module.exports = merge(sharedConfig, { | ||||
mode: 'development', | |||||
devtool: 'cheap-module-eval-source-map', | devtool: 'cheap-module-eval-source-map', | ||||
stats: { | stats: { | ||||
@@ -1,15 +1,22 @@ | |||||
const ExtractTextPlugin = require('extract-text-webpack-plugin'); | |||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |||||
const { env } = require('../configuration.js'); | const { env } = require('../configuration.js'); | ||||
module.exports = { | module.exports = { | ||||
test: /\.(scss|sass|css)$/i, | |||||
use: ExtractTextPlugin.extract({ | |||||
fallback: 'style-loader', | |||||
use: [ | |||||
{ loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } }, | |||||
{ loader: 'postcss-loader', options: { sourceMap: true } }, | |||||
'resolve-url-loader', | |||||
'sass-loader', | |||||
], | |||||
}), | |||||
test: /\.s?css$/i, | |||||
use: [ | |||||
MiniCssExtractPlugin.loader, | |||||
{ | |||||
loader: 'css-loader', | |||||
options: { | |||||
minimize: env.NODE_ENV === 'production', | |||||
}, | |||||
}, | |||||
{ | |||||
loader: 'postcss-loader', | |||||
options: { | |||||
sourceMap: true, | |||||
}, | |||||
}, | |||||
'sass-loader', | |||||
], | |||||
}; | }; |
@@ -1,7 +1,7 @@ | |||||
// Note: You must restart bin/webpack-dev-server for changes to take effect | // Note: You must restart bin/webpack-dev-server for changes to take effect | ||||
const webpack = require('webpack'); | |||||
const merge = require('webpack-merge'); | const merge = require('webpack-merge'); | ||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); | |||||
const CompressionPlugin = require('compression-webpack-plugin'); | const CompressionPlugin = require('compression-webpack-plugin'); | ||||
const sharedConfig = require('./shared.js'); | const sharedConfig = require('./shared.js'); | ||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; | ||||
@@ -36,6 +36,8 @@ if (process.env.S3_ENABLED === 'true') { | |||||
} | } | ||||
module.exports = merge(sharedConfig, { | module.exports = merge(sharedConfig, { | ||||
mode: 'production', | |||||
output: { | output: { | ||||
filename: '[name]-[chunkhash].js', | filename: '[name]-[chunkhash].js', | ||||
chunkFilename: '[name]-[chunkhash].js', | chunkFilename: '[name]-[chunkhash].js', | ||||
@@ -44,19 +46,28 @@ module.exports = merge(sharedConfig, { | |||||
devtool: 'source-map', // separate sourcemap file, suitable for production | devtool: 'source-map', // separate sourcemap file, suitable for production | ||||
stats: 'normal', | stats: 'normal', | ||||
plugins: [ | |||||
new webpack.optimize.UglifyJsPlugin({ | |||||
sourceMap: true, | |||||
mangle: true, | |||||
optimization: { | |||||
minimize: true, | |||||
minimizer: [ | |||||
new UglifyJsPlugin({ | |||||
sourceMap: true, | |||||
compress: { | |||||
warnings: false, | |||||
}, | |||||
uglifyOptions: { | |||||
mangle: true, | |||||
output: { | |||||
comments: false, | |||||
}, | |||||
}), | |||||
compress: { | |||||
warnings: false, | |||||
}, | |||||
output: { | |||||
comments: false, | |||||
}, | |||||
}, | |||||
}), | |||||
], | |||||
}, | |||||
plugins: [ | |||||
new CompressionPlugin({ | new CompressionPlugin({ | ||||
asset: '[path].gz[query]', | asset: '[path].gz[query]', | ||||
algorithm: compressionAlgorithm, | algorithm: compressionAlgorithm, | ||||
@@ -1,9 +1,9 @@ | |||||
// Note: You must restart bin/webpack-dev-server for changes to take effect | // Note: You must restart bin/webpack-dev-server for changes to take effect | ||||
const webpack = require('webpack'); | const webpack = require('webpack'); | ||||
const { basename, dirname, join, relative, resolve, sep } = require('path'); | |||||
const { basename, dirname, join, relative, resolve } = require('path'); | |||||
const { sync } = require('glob'); | const { sync } = require('glob'); | ||||
const ExtractTextPlugin = require('extract-text-webpack-plugin'); | |||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |||||
const ManifestPlugin = require('webpack-manifest-plugin'); | const ManifestPlugin = require('webpack-manifest-plugin'); | ||||
const extname = require('path-complete-extname'); | const extname = require('path-complete-extname'); | ||||
const { env, settings, themes, output, loadersDir } = require('./configuration.js'); | const { env, settings, themes, output, loadersDir } = require('./configuration.js'); | ||||
@@ -39,6 +39,26 @@ module.exports = { | |||||
publicPath: output.publicPath, | publicPath: output.publicPath, | ||||
}, | }, | ||||
optimization: { | |||||
runtimeChunk: { | |||||
name: 'common', | |||||
}, | |||||
splitChunks: { | |||||
cacheGroups: { | |||||
default: false, | |||||
vendors: false, | |||||
common: { | |||||
name: 'common', | |||||
chunks: 'all', | |||||
minChunks: 2, | |||||
minSize: 0, | |||||
test: /^(?!.*[\\\/]node_modules[\\\/]react-intl[\\\/]).+$/, | |||||
}, | |||||
}, | |||||
}, | |||||
occurrenceOrder: true, | |||||
}, | |||||
module: { | module: { | ||||
rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)), | rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)), | ||||
}, | }, | ||||
@@ -52,25 +72,13 @@ module.exports = { | |||||
resource.request = resource.request.replace(/^history/, 'history/es'); | resource.request = resource.request.replace(/^history/, 'history/es'); | ||||
} | } | ||||
), | ), | ||||
new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css'), | |||||
new MiniCssExtractPlugin({ | |||||
filename: env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css', | |||||
}), | |||||
new ManifestPlugin({ | new ManifestPlugin({ | ||||
publicPath: output.publicPath, | publicPath: output.publicPath, | ||||
writeToFileEmit: true, | writeToFileEmit: true, | ||||
}), | |||||
new webpack.optimize.CommonsChunkPlugin({ | |||||
name: 'common', | |||||
minChunks: (module, count) => { | |||||
const reactIntlPathRegexp = new RegExp(`node_modules\\${sep}react-intl`); | |||||
if (module.resource && reactIntlPathRegexp.test(module.resource)) { | |||||
// skip react-intl because it's useless to put in the common chunk, | |||||
// e.g. because "shared" modules between zh-TW and zh-CN will never | |||||
// be loaded together | |||||
return false; | |||||
} | |||||
return count >= 2; | |||||
}, | |||||
filter: file => !file.isAsset || file.isModuleAsset, | |||||
}), | }), | ||||
], | ], | ||||
@@ -3,4 +3,6 @@ | |||||
const merge = require('webpack-merge'); | const merge = require('webpack-merge'); | ||||
const sharedConfig = require('./shared.js'); | const sharedConfig = require('./shared.js'); | ||||
module.exports = merge(sharedConfig, {}); | |||||
module.exports = merge(sharedConfig, { | |||||
mode: 'development', | |||||
}); |
@@ -21,29 +21,29 @@ | |||||
"private": true, | "private": true, | ||||
"dependencies": { | "dependencies": { | ||||
"array-includes": "^3.0.3", | "array-includes": "^3.0.3", | ||||
"autoprefixer": "^7.1.6", | |||||
"autoprefixer": "^8.6.5", | |||||
"axios": "~0.16.2", | "axios": "~0.16.2", | ||||
"babel-core": "^6.25.0", | |||||
"babel-loader": "^7.1.1", | |||||
"babel-plugin-lodash": "^3.3.2", | |||||
"babel-core": "^6.26.3", | |||||
"babel-loader": "^7.1.5", | |||||
"babel-plugin-lodash": "^3.3.4", | |||||
"babel-plugin-preval": "^1.6.1", | "babel-plugin-preval": "^1.6.1", | ||||
"babel-plugin-react-intl": "^2.3.1", | |||||
"babel-plugin-react-intl": "^2.4.0", | |||||
"babel-plugin-syntax-dynamic-import": "^6.18.0", | "babel-plugin-syntax-dynamic-import": "^6.18.0", | ||||
"babel-plugin-transform-class-properties": "^6.24.1", | "babel-plugin-transform-class-properties": "^6.24.1", | ||||
"babel-plugin-transform-decorators-legacy": "^1.3.4", | |||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", | |||||
"babel-plugin-transform-decorators-legacy": "^1.3.5", | |||||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", | |||||
"babel-plugin-transform-object-rest-spread": "^6.23.0", | "babel-plugin-transform-object-rest-spread": "^6.23.0", | ||||
"babel-plugin-transform-react-inline-elements": "^6.22.0", | "babel-plugin-transform-react-inline-elements": "^6.22.0", | ||||
"babel-plugin-transform-react-jsx-self": "^6.22.0", | "babel-plugin-transform-react-jsx-self": "^6.22.0", | ||||
"babel-plugin-transform-react-jsx-source": "^6.22.0", | "babel-plugin-transform-react-jsx-source": "^6.22.0", | ||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.10", | |||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.13", | |||||
"babel-plugin-transform-runtime": "^6.23.0", | "babel-plugin-transform-runtime": "^6.23.0", | ||||
"babel-preset-env": "^1.6.1", | |||||
"babel-preset-env": "^1.7.0", | |||||
"babel-preset-react": "^6.24.1", | "babel-preset-react": "^6.24.1", | ||||
"classnames": "^2.2.5", | "classnames": "^2.2.5", | ||||
"compression-webpack-plugin": "^1.0.1", | |||||
"cross-env": "^5.1.1", | |||||
"css-loader": "^0.28.4", | |||||
"compression-webpack-plugin": "^1.1.11", | |||||
"cross-env": "^5.1.4", | |||||
"css-loader": "^0.28.11", | |||||
"detect-passive-events": "^1.0.2", | "detect-passive-events": "^1.0.2", | ||||
"dotenv": "^4.0.0", | "dotenv": "^4.0.0", | ||||
"emoji-mart": "Gargron/emoji-mart#build", | "emoji-mart": "Gargron/emoji-mart#build", | ||||
@@ -51,8 +51,7 @@ | |||||
"escape-html": "^1.0.3", | "escape-html": "^1.0.3", | ||||
"exif-js": "^2.3.0", | "exif-js": "^2.3.0", | ||||
"express": "^4.16.2", | "express": "^4.16.2", | ||||
"extract-text-webpack-plugin": "^3.0.2", | |||||
"file-loader": "^0.11.2", | |||||
"file-loader": "^1.1.11", | |||||
"font-awesome": "^4.7.0", | "font-awesome": "^4.7.0", | ||||
"glob": "^7.1.1", | "glob": "^7.1.1", | ||||
"http-link-header": "^0.8.0", | "http-link-header": "^0.8.0", | ||||
@@ -63,27 +62,28 @@ | |||||
"intl-messageformat": "^2.2.0", | "intl-messageformat": "^2.2.0", | ||||
"intl-relativeformat": "^2.1.0", | "intl-relativeformat": "^2.1.0", | ||||
"is-nan": "^1.2.1", | "is-nan": "^1.2.1", | ||||
"js-yaml": "^3.9.0", | |||||
"lodash": "^4.17.4", | |||||
"js-yaml": "^3.11.0", | |||||
"lodash": "^4.17.5", | |||||
"mark-loader": "^0.1.6", | "mark-loader": "^0.1.6", | ||||
"marky": "^1.2.0", | "marky": "^1.2.0", | ||||
"mini-css-extract-plugin": "^0.4.1", | |||||
"mkdirp": "^0.5.1", | "mkdirp": "^0.5.1", | ||||
"node-sass": "^4.7.2", | |||||
"node-sass": "^4.9.2", | |||||
"npm-run-all": "^4.1.2", | "npm-run-all": "^4.1.2", | ||||
"npmlog": "^4.1.2", | "npmlog": "^4.1.2", | ||||
"object-assign": "^4.1.1", | "object-assign": "^4.1.1", | ||||
"object-fit-images": "^3.2.3", | "object-fit-images": "^3.2.3", | ||||
"object.values": "^1.0.4", | "object.values": "^1.0.4", | ||||
"offline-plugin": "^4.8.3", | |||||
"path-complete-extname": "^0.1.0", | |||||
"offline-plugin": "^5.0.5", | |||||
"path-complete-extname": "^1.0.0", | |||||
"pg": "^6.4.0", | "pg": "^6.4.0", | ||||
"postcss-loader": "^2.0.9", | |||||
"postcss-loader": "^2.1.6", | |||||
"postcss-object-fit-images": "^1.1.2", | "postcss-object-fit-images": "^1.1.2", | ||||
"postcss-smart-import": "^0.7.5", | |||||
"precss": "^2.0.0", | |||||
"postcss-smart-import": "^0.7.6", | |||||
"precss": "^3.1.2", | |||||
"prop-types": "^15.5.10", | "prop-types": "^15.5.10", | ||||
"punycode": "^2.1.0", | "punycode": "^2.1.0", | ||||
"rails-ujs": "^5.1.2", | |||||
"rails-ujs": "^5.2.0", | |||||
"react": "^16.3.0", | "react": "^16.3.0", | ||||
"react-dom": "^16.3.0", | "react-dom": "^16.3.0", | ||||
"react-hotkeys": "^0.10.0", | "react-hotkeys": "^0.10.0", | ||||
@@ -107,25 +107,26 @@ | |||||
"redux-thunk": "^2.2.0", | "redux-thunk": "^2.2.0", | ||||
"requestidlecallback": "^0.3.0", | "requestidlecallback": "^0.3.0", | ||||
"reselect": "^3.0.1", | "reselect": "^3.0.1", | ||||
"resolve-url-loader": "^2.2.0", | |||||
"rimraf": "^2.6.1", | "rimraf": "^2.6.1", | ||||
"sass-loader": "^6.0.6", | |||||
"sass-loader": "^7.0.3", | |||||
"stringz": "^0.3.0", | "stringz": "^0.3.0", | ||||
"style-loader": "^0.19.0", | |||||
"style-loader": "^0.21.0", | |||||
"substring-trie": "^1.0.2", | "substring-trie": "^1.0.2", | ||||
"throng": "^4.0.0", | "throng": "^4.0.0", | ||||
"tiny-queue": "^0.2.1", | "tiny-queue": "^0.2.1", | ||||
"uglifyjs-webpack-plugin": "^1.2.7", | |||||
"uuid": "^3.1.0", | "uuid": "^3.1.0", | ||||
"uws": "^10.148.0", | |||||
"webpack": "^3.9.1", | |||||
"webpack-bundle-analyzer": "^2.9.1", | |||||
"webpack-manifest-plugin": "^1.2.1", | |||||
"webpack-merge": "^4.1.1", | |||||
"uws": "^10.148.1", | |||||
"webpack": "^4.16.0", | |||||
"webpack-bundle-analyzer": "^2.13.1", | |||||
"webpack-cli": "^3.0.8", | |||||
"webpack-manifest-plugin": "^2.0.3", | |||||
"webpack-merge": "^4.1.3", | |||||
"websocket.js": "^0.1.12", | "websocket.js": "^0.1.12", | ||||
"whatwg-url": "^6.4.1" | "whatwg-url": "^6.4.1" | ||||
}, | }, | ||||
"devDependencies": { | "devDependencies": { | ||||
"babel-eslint": "^8.2.3", | |||||
"babel-eslint": "^8.2.6", | |||||
"enzyme": "^3.2.0", | "enzyme": "^3.2.0", | ||||
"enzyme-adapter-react-16": "^1.1.0", | "enzyme-adapter-react-16": "^1.1.0", | ||||
"eslint": "^4.19.1", | "eslint": "^4.19.1", | ||||
@@ -135,9 +136,9 @@ | |||||
"eslint-plugin-react": "^7.8.2", | "eslint-plugin-react": "^7.8.2", | ||||
"jest": "^21.2.1", | "jest": "^21.2.1", | ||||
"raf": "^3.4.0", | "raf": "^3.4.0", | ||||
"react-intl-translations-manager": "^5.0.0", | |||||
"react-intl-translations-manager": "^5.0.3", | |||||
"react-test-renderer": "^16.2.0", | "react-test-renderer": "^16.2.0", | ||||
"webpack-dev-server": "^2.9.5", | |||||
"webpack-dev-server": "^3.1.4", | |||||
"yargs": "^8.0.2" | "yargs": "^8.0.2" | ||||
}, | }, | ||||
"optionalDependencies": { | "optionalDependencies": { | ||||