about summary refs log tree commit diff
path: root/config
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-05-03 02:04:16 +0200
committerGitHub <noreply@github.com>2017-05-03 02:04:16 +0200
commitf5bf5ebb82e3af420dcd23d602b1be6cc86838e1 (patch)
tree92eef08642a038cf44ccbc6d16a884293e7a0814 /config
parent26bc5915727e0a0173c03cb49f5193dd612fb888 (diff)
Replace sprockets/browserify with Webpack (#2617)
* Replace browserify with webpack

* Add react-intl-translations-manager

* Do not minify in development, add offline-plugin for ServiceWorker background cache updates

* Adjust tests and dependencies

* Fix production deployments

* Fix tests

* More optimizations

* Improve travis cache for npm stuff

* Re-run travis

* Add back support for custom.scss as before

* Remove offline-plugin and babili

* Fix issue with Immutable.List().unshift(...values) not working as expected

* Make travis load schema instead of running all migrations in sequence

* Fix missing React import in WarningContainer. Optimize rendering performance by using ImmutablePureComponent instead of
React.PureComponent. ImmutablePureComponent uses Immutable.is() to compare props. Replace dynamic callback bindings in
<UI />

* Add react definitions to places that use JSX

* Add Procfile.dev for running rails, webpack and streaming API at the same time
Diffstat (limited to 'config')
-rw-r--r--config/application.rb4
-rw-r--r--config/environments/development.rb2
-rw-r--r--config/environments/production.rb2
-rw-r--r--config/initializers/assets.rb2
-rw-r--r--config/webpack/configuration.js26
-rw-r--r--config/webpack/development.js16
-rw-r--r--config/webpack/development.server.js18
-rw-r--r--config/webpack/development.server.yml17
-rw-r--r--config/webpack/loaders/assets.js12
-rw-r--r--config/webpack/loaders/babel.js5
-rw-r--r--config/webpack/loaders/coffee.js4
-rw-r--r--config/webpack/loaders/erb.js9
-rw-r--r--config/webpack/loaders/sass.js14
-rw-r--r--config/webpack/paths.yml33
-rw-r--r--config/webpack/production.js44
-rw-r--r--config/webpack/shared.js59
-rw-r--r--config/webpack/test.js6
-rw-r--r--config/webpack/translationRunner.js34
18 files changed, 298 insertions, 9 deletions
diff --git a/config/application.rb b/config/application.rb
index 2e7e5cd49..1b5820fa3 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -74,10 +74,6 @@ module Mastodon
     config.middleware.use Rack::Attack
     config.middleware.use Rack::Deflater
 
-    # babel config can be found in .babelrc
-    config.browserify_rails.commandline_options   = '--transform babelify --extension=".jsx"'
-    config.browserify_rails.evaluate_node_modules = true
-
     config.to_prepare do
       Doorkeeper::AuthorizationsController.layout 'public'
       Doorkeeper::AuthorizedApplicationsController.layout 'admin'
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 6157f20d3..4b25ab1a8 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -75,8 +75,6 @@ Rails.application.configure do
 
     Bullet.add_whitelist type: :n_plus_one_query, class_name: 'User', association: :account
   end
-
-  config.react.variant = :development
 end
 
 require 'sidekiq/testing'
diff --git a/config/environments/production.rb b/config/environments/production.rb
index a1cd0fb35..1f2b5e05d 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -106,8 +106,6 @@ Rails.application.configure do
 
   config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym
 
-  config.react.variant = :production
-
   config.to_prepare do
     StatsD.backend = StatsD::Instrument::Backends::NullBackend.new if ENV['STATSD_ADDR'].blank?
   end
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index e6bd8a015..f2bf17364 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -8,6 +8,6 @@ Rails.application.config.assets.version = '1.0'
 
 # Precompile additional assets.
 # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
-Rails.application.config.assets.precompile += %w(application_public.js custom.css)
+# Rails.application.config.assets.precompile += %w(application_public.js custom.css)
 
 Rails.application.config.assets.initialize_on_precompile = true
diff --git a/config/webpack/configuration.js b/config/webpack/configuration.js
new file mode 100644
index 000000000..61c5b821f
--- /dev/null
+++ b/config/webpack/configuration.js
@@ -0,0 +1,26 @@
+// Common configuration for webpacker loaded from config/webpack/paths.yml
+
+const { join, resolve } = require('path')
+const { env } = require('process')
+const { safeLoad } = require('js-yaml')
+const { readFileSync } = require('fs')
+
+const configPath = resolve('config', 'webpack')
+const loadersDir = join(__dirname, 'loaders')
+const paths = safeLoad(readFileSync(join(configPath, 'paths.yml'), 'utf8'))[env.NODE_ENV]
+const devServer = safeLoad(readFileSync(join(configPath, 'development.server.yml'), 'utf8'))[env.NODE_ENV]
+
+// Compute public path based on environment and CDN_HOST in production
+const ifHasCDN = env.CDN_HOST !== undefined && env.NODE_ENV === 'production'
+const devServerUrl = `http://${devServer.host}:${devServer.port}/${paths.entry}/`
+const publicUrl = ifHasCDN ? `${env.CDN_HOST}/${paths.entry}/` : `/${paths.entry}/`
+const publicPath = env.NODE_ENV !== 'production' ? devServerUrl : publicUrl
+
+module.exports = {
+  devServer,
+  env,
+  paths,
+  loadersDir,
+  publicUrl,
+  publicPath
+}
diff --git a/config/webpack/development.js b/config/webpack/development.js
new file mode 100644
index 000000000..7dfa2df11
--- /dev/null
+++ b/config/webpack/development.js
@@ -0,0 +1,16 @@
+// Note: You must restart bin/webpack-dev-server for changes to take effect
+
+const merge = require('webpack-merge')
+const sharedConfig = require('./shared.js')
+
+module.exports = merge(sharedConfig, {
+  devtool: 'sourcemap',
+
+  stats: {
+    errorDetails: true
+  },
+
+  output: {
+    pathinfo: true
+  }
+})
diff --git a/config/webpack/development.server.js b/config/webpack/development.server.js
new file mode 100644
index 000000000..5c5631a4e
--- /dev/null
+++ b/config/webpack/development.server.js
@@ -0,0 +1,18 @@
+// Note: You must restart bin/webpack-dev-server for changes to take effect
+
+const { resolve } = require('path')
+const merge = require('webpack-merge')
+const devConfig = require('./development.js')
+const { devServer, publicPath, paths } = require('./configuration.js')
+
+module.exports = merge(devConfig, {
+  devServer: {
+    host: devServer.host,
+    port: devServer.port,
+    headers: { "Access-Control-Allow-Origin": "*" },
+    compress: true,
+    historyApiFallback: true,
+    contentBase: resolve(paths.output, paths.entry),
+    publicPath
+  }
+})
diff --git a/config/webpack/development.server.yml b/config/webpack/development.server.yml
new file mode 100644
index 000000000..ee588a888
--- /dev/null
+++ b/config/webpack/development.server.yml
@@ -0,0 +1,17 @@
+# Note: You must restart bin/webpack-dev-server for changes to take effect
+
+default: &default
+  enabled: true
+  host: localhost
+  port: 8080
+
+development:
+  <<: *default
+
+test:
+  <<: *default
+  enabled: false
+
+production:
+  <<: *default
+  enabled: false
diff --git a/config/webpack/loaders/assets.js b/config/webpack/loaders/assets.js
new file mode 100644
index 000000000..595f073fc
--- /dev/null
+++ b/config/webpack/loaders/assets.js
@@ -0,0 +1,12 @@
+const { env, publicPath } = require('../configuration.js')
+
+module.exports = {
+  test: /\.(jpg|jpeg|png|gif|svg|eot|ttf|woff|woff2)$/i,
+  use: [{
+    loader: 'file-loader',
+    options: {
+      publicPath,
+      name: env.NODE_ENV === 'production' ? '[name]-[hash].[ext]' : '[name].[ext]'
+    }
+  }]
+}
diff --git a/config/webpack/loaders/babel.js b/config/webpack/loaders/babel.js
new file mode 100644
index 000000000..c608e708f
--- /dev/null
+++ b/config/webpack/loaders/babel.js
@@ -0,0 +1,5 @@
+module.exports = {
+  test: /\.js(\.erb)?$/,
+  exclude: /node_modules/,
+  loader: 'babel-loader'
+}
diff --git a/config/webpack/loaders/coffee.js b/config/webpack/loaders/coffee.js
new file mode 100644
index 000000000..dae874249
--- /dev/null
+++ b/config/webpack/loaders/coffee.js
@@ -0,0 +1,4 @@
+module.exports = {
+  test: /\.coffee(\.erb)?$/,
+  loader: 'coffee-loader'
+}
diff --git a/config/webpack/loaders/erb.js b/config/webpack/loaders/erb.js
new file mode 100644
index 000000000..4cd7d6849
--- /dev/null
+++ b/config/webpack/loaders/erb.js
@@ -0,0 +1,9 @@
+module.exports = {
+  test: /\.erb$/,
+  enforce: 'pre',
+  exclude: /node_modules/,
+  loader: 'rails-erb-loader',
+  options: {
+    runner: 'bin/rails runner'
+  }
+}
diff --git a/config/webpack/loaders/sass.js b/config/webpack/loaders/sass.js
new file mode 100644
index 000000000..2cb0e759a
--- /dev/null
+++ b/config/webpack/loaders/sass.js
@@ -0,0 +1,14 @@
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const { env } = require('../configuration.js')
+
+module.exports = {
+  test: /\.(scss|sass|css)$/i,
+  use: ExtractTextPlugin.extract({
+    fallback: 'style-loader',
+    use: [
+      { loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } },
+      'postcss-loader',
+      'sass-loader'
+    ]
+  })
+}
diff --git a/config/webpack/paths.yml b/config/webpack/paths.yml
new file mode 100644
index 000000000..26ab8facc
--- /dev/null
+++ b/config/webpack/paths.yml
@@ -0,0 +1,33 @@
+# Note: You must restart bin/webpack-dev-server for changes to take effect
+
+default: &default
+  config: config/webpack
+  entry: packs
+  output: public
+  manifest: manifest.json
+  node_modules: node_modules
+  source: app/javascript
+  extensions:
+    - .coffee
+    - .js
+    - .jsx
+    - .ts
+    - .vue
+    - .sass
+    - .scss
+    - .css
+    - .png
+    - .svg
+    - .gif
+    - .jpeg
+    - .jpg
+
+development:
+  <<: *default
+
+test:
+  <<: *default
+  manifest: manifest-test.json
+
+production:
+  <<: *default
diff --git a/config/webpack/production.js b/config/webpack/production.js
new file mode 100644
index 000000000..2e4baa424
--- /dev/null
+++ b/config/webpack/production.js
@@ -0,0 +1,44 @@
+// Note: You must restart bin/webpack-dev-server for changes to take effect
+
+/* eslint global-require: 0 */
+
+const webpack = require('webpack')
+const merge = require('webpack-merge')
+const CompressionPlugin = require('compression-webpack-plugin')
+const sharedConfig = require('./shared.js')
+
+module.exports = merge(sharedConfig, {
+  output: { filename: '[name]-[chunkhash].js' },
+
+  plugins: [
+    new webpack.optimize.UglifyJsPlugin({
+      compress: {
+        unused: true,
+        evaluate: true,
+        booleans: true,
+        drop_debugger: true,
+        dead_code: true,
+        pure_getters: true,
+        negate_iife: true,
+        conditionals: true,
+        loops: true,
+        cascade: true,
+        keep_fargs: false,
+        warnings: true
+      },
+
+      mangle: false,
+
+      output: {
+        comments: false
+      },
+
+      sourceMap: false
+    }),
+    new CompressionPlugin({
+      asset: '[path].gz[query]',
+      algorithm: 'gzip',
+      test: /\.(js|css|svg|eot|ttf|woff|woff2)$/
+    })
+  ]
+})
diff --git a/config/webpack/shared.js b/config/webpack/shared.js
new file mode 100644
index 000000000..3d1b14e15
--- /dev/null
+++ b/config/webpack/shared.js
@@ -0,0 +1,59 @@
+// Note: You must restart bin/webpack-dev-server for changes to take effect
+
+/* eslint global-require: 0 */
+/* eslint import/no-dynamic-require: 0 */
+
+const webpack = require('webpack')
+const { basename, dirname, join, relative, resolve } = require('path')
+const { sync } = require('glob')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const ManifestPlugin = require('webpack-manifest-plugin')
+const extname = require('path-complete-extname')
+const { env, paths, publicPath, loadersDir } = require('./configuration.js')
+
+const extensionGlob = `**/*{${paths.extensions.join(',')}}*`
+const packPaths = sync(join(paths.source, paths.entry, extensionGlob))
+
+module.exports = {
+  entry: packPaths.reduce(
+    (map, entry) => {
+      const localMap = map
+      const namespace = relative(join(paths.source, paths.entry), dirname(entry))
+      localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry)
+      return localMap
+    }, {}
+  ),
+
+  output: {
+    filename: '[name].js',
+    chunkFilename: '[name]-[chunkhash].js',
+    path: resolve(paths.output, paths.entry),
+    publicPath
+  },
+
+  module: {
+    rules: sync(join(loadersDir, '*.js')).map(loader => require(loader))
+  },
+
+  plugins: [
+    new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
+    new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
+    new ManifestPlugin({ fileName: paths.manifest, publicPath, writeToFileEmit: true }),
+    new webpack.optimize.CommonsChunkPlugin({
+      name: 'vendor',
+      minChunks: ({ resource }) => /node_modules/.test(resource)
+    })
+  ],
+
+  resolve: {
+    extensions: paths.extensions,
+    modules: [
+      resolve(paths.source),
+      resolve(paths.node_modules)
+    ]
+  },
+
+  resolveLoader: {
+    modules: [paths.node_modules]
+  }
+}
diff --git a/config/webpack/test.js b/config/webpack/test.js
new file mode 100644
index 000000000..e002d0cdc
--- /dev/null
+++ b/config/webpack/test.js
@@ -0,0 +1,6 @@
+// Note: You must restart bin/webpack-dev-server for changes to take effect
+
+const merge = require('webpack-merge')
+const sharedConfig = require('./shared.js')
+
+module.exports = merge(sharedConfig, {})
diff --git a/config/webpack/translationRunner.js b/config/webpack/translationRunner.js
new file mode 100644
index 000000000..c636170b9
--- /dev/null
+++ b/config/webpack/translationRunner.js
@@ -0,0 +1,34 @@
+const manageTranslations = require('react-intl-translations-manager').default;
+
+manageTranslations({
+  messagesDirectory: 'build/messages',
+  translationsDirectory: 'app/javascript/mastodon/locales/',
+  detectDuplicateIds: false,
+  singleMessagesFile: true,
+  languages: [
+    'ar',
+    'en',
+    'de',
+    'es',
+    'fa',
+    'hr',
+    'hu',
+    'io',
+    'it',
+    'fr',
+    'nl',
+    'no',
+    'oc',
+    'pt',
+    'pt-BR',
+    'uk',
+    'fi',
+    'eo',
+    'ru',
+    'ja',
+    'zh-HK',
+    'zh-CN',
+    'bg',
+    'id',
+  ],
+})