Browse Source

Bump webpacker from 3.5.5 to 4.0.2 (#10277)

Bumps [webpacker](https://github.com/rails/webpacker) from 3.5.5 to 4.0.2.
- [Release notes](https://github.com/rails/webpacker/releases)
- [Changelog](https://github.com/rails/webpacker/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/webpacker/compare/v3.5.5...v4.0.2)

Signed-off-by: dependabot[bot] <support@dependabot.com>
Co-authored-by: Yamagishi Kazutoshi <ykzts@desire.sh>
Yamagishi Kazutoshi 5 years ago
parent
commit
8347479f5d
46 changed files with 774 additions and 420 deletions
  1. 1 1
      Gemfile
  2. 3 3
      Gemfile.lock
  3. 1 1
      app/serializers/rest/instance_serializer.rb
  4. 1 1
      app/serializers/rss/account_serializer.rb
  5. 1 1
      app/serializers/rss/tag_serializer.rb
  6. 2 2
      app/views/about/more.html.haml
  7. 2 2
      app/views/about/show.html.haml
  8. 1 1
      app/views/application/_sidebar.html.haml
  9. 1 1
      app/views/home/index.html.haml
  10. 1 1
      app/views/layouts/admin.html.haml
  11. 1 1
      app/views/layouts/auth.html.haml
  12. 2 2
      app/views/layouts/mailer.html.haml
  13. 1 1
      app/views/layouts/public.html.haml
  14. 1 1
      app/views/notification_mailer/favourite.html.haml
  15. 1 1
      app/views/notification_mailer/follow.html.haml
  16. 1 1
      app/views/notification_mailer/follow_request.html.haml
  17. 1 1
      app/views/notification_mailer/mention.html.haml
  18. 1 1
      app/views/notification_mailer/reblog.html.haml
  19. 1 1
      app/views/shared/_og.html.haml
  20. 1 1
      app/views/user_mailer/backup_ready.html.haml
  21. 1 1
      app/views/user_mailer/confirmation_instructions.html.haml
  22. 1 1
      app/views/user_mailer/email_changed.html.haml
  23. 1 1
      app/views/user_mailer/password_change.html.haml
  24. 1 1
      app/views/user_mailer/reconfirmation_instructions.html.haml
  25. 1 1
      app/views/user_mailer/reset_password_instructions.html.haml
  26. 1 1
      app/views/user_mailer/warning.html.haml
  27. 1 1
      app/views/user_mailer/welcome.html.haml
  28. 5 1
      bin/webpack
  29. 5 1
      bin/webpack-dev-server
  30. 1 3
      config/webpack/configuration.js
  31. 28 12
      config/webpack/development.js
  32. 0 12
      config/webpack/loaders/assets.js
  33. 0 12
      config/webpack/loaders/babel.js
  34. 0 21
      config/webpack/loaders/babel_external.js
  35. 12 16
      config/webpack/production.js
  36. 21 0
      config/webpack/rules/babel.js
  37. 8 1
      config/webpack/rules/css.js
  38. 20 0
      config/webpack/rules/file.js
  39. 14 0
      config/webpack/rules/index.js
  40. 0 0
      config/webpack/rules/mark.js
  41. 26 0
      config/webpack/rules/node_modules.js
  42. 11 6
      config/webpack/shared.js
  43. 41 4
      config/webpacker.yml
  44. 0 29
      jest.config.js
  45. 53 27
      package.json
  46. 497 243
      yarn.lock

+ 1 - 1
Gemfile

@@ -86,7 +86,7 @@ gem 'tty-command', '~> 0.8', require: false
 gem 'tty-prompt', '~> 0.18', require: false
 gem 'twitter-text', '~> 1.14'
 gem 'tzinfo-data', '~> 1.2018'
-gem 'webpacker', '~> 3.5'
+gem 'webpacker', '~> 4.0'
 gem 'webpush'
 
 gem 'json-ld', '~> 3.0'

+ 3 - 3
Gemfile.lock

@@ -433,7 +433,7 @@ GEM
     rack-cors (1.0.2)
     rack-protection (2.0.5)
       rack
-    rack-proxy (0.6.4)
+    rack-proxy (0.6.5)
       rack
     rack-test (1.1.0)
       rack (>= 1.0, < 3)
@@ -640,7 +640,7 @@ GEM
       addressable (>= 2.3.6)
       crack (>= 0.3.2)
       hashdiff
-    webpacker (3.5.5)
+    webpacker (4.0.2)
       activesupport (>= 4.2)
       rack-proxy (>= 0.6.1)
       railties (>= 4.2)
@@ -772,7 +772,7 @@ DEPENDENCIES
   twitter-text (~> 1.14)
   tzinfo-data (~> 1.2018)
   webmock (~> 3.5)
-  webpacker (~> 3.5)
+  webpacker (~> 4.0)
   webpush
 
 RUBY VERSION

+ 1 - 1
app/serializers/rest/instance_serializer.rb

@@ -32,7 +32,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
   end
 
   def thumbnail
-    instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url) : full_pack_url('preview.jpg')
+    instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url) : full_pack_url('media/images/preview.jpg')
   end
 
   def stats

+ 1 - 1
app/serializers/rss/account_serializer.rb

@@ -11,7 +11,7 @@ class RSS::AccountSerializer
     builder.title("#{display_name(account)} (@#{account.local_username_and_domain})")
            .description(account_description(account))
            .link(TagManager.instance.url_for(account))
-           .logo(full_asset_url(asset_pack_path('logo.svg')))
+           .logo(full_pack_url('media/images/logo.svg'))
            .accent_color('2b90d9')
 
     builder.image(full_asset_url(account.avatar.url(:original))) if account.avatar?

+ 1 - 1
app/serializers/rss/tag_serializer.rb

@@ -12,7 +12,7 @@ class RSS::TagSerializer
     builder.title("##{tag.name}")
            .description(strip_tags(I18n.t('about.about_hashtag_html', hashtag: tag.name)))
            .link(tag_url(tag))
-           .logo(full_asset_url(asset_pack_path('logo.svg')))
+           .logo(full_pack_url('media/images/logo.svg'))
            .accent_color('2b90d9')
 
     statuses.each do |status|

+ 2 - 2
app/views/about/more.html.haml

@@ -9,7 +9,7 @@
   .column-0
     .public-account-header.public-account-header--no-bar
       .public-account-header__image
-        = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title, class: 'parallax'
+        = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title, class: 'parallax'
 
   .column-1
     .landing-page__call-to-action{ dir: 'ltr' }
@@ -25,7 +25,7 @@
             %span= t 'about.status_count_after', count: @instance_presenter.status_count
         .row__mascot
           .landing-page__mascot
-            = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('elephant_ui_plane.svg'), alt: ''
+            = image_tag @instance_presenter.mascot&.file&.url || asset_pack_path('media/images/elephant_ui_plane.svg'), alt: ''
 
   .column-2
     .landing-page__information.contact-widget

+ 2 - 2
app/views/about/show.html.haml

@@ -8,7 +8,7 @@
 .landing
   .landing__brand
     = link_to root_url, class: 'brand' do
-      = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+      = image_pack_tag 'logo_full.svg', alt: 'Mastodon'
       %span.brand__tagline=t 'about.tagline'
 
   .landing__grid
@@ -48,7 +48,7 @@
 
       .hero-widget
         .hero-widget__img
-          = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
+          = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title
 
         - if @instance_presenter.site_short_description.present?
           .hero-widget__text

+ 1 - 1
app/views/application/_sidebar.html.haml

@@ -1,6 +1,6 @@
 .hero-widget
   .hero-widget__img
-    = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('preview.jpg'), alt: @instance_presenter.site_title
+    = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg'), alt: @instance_presenter.site_title
 
   .hero-widget__text
     %p= @instance_presenter.site_short_description.html_safe.presence || @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)

+ 1 - 1
app/views/home/index.html.haml

@@ -11,7 +11,7 @@
 
 .app-holder#mastodon{ data: { props: Oj.dump(default_props) } }
   %noscript
-    = image_tag asset_pack_path('logo.svg'), alt: 'Mastodon'
+    = image_pack_tag 'logo.svg', alt: 'Mastodon'
 
     %div
       = t('errors.noscript_html', apps_path: 'https://joinmastodon.org/apps')

+ 1 - 1
app/views/layouts/admin.html.haml

@@ -6,7 +6,7 @@
     .sidebar-wrapper
       .sidebar
         = link_to root_path do
-          = image_tag asset_pack_path('logo.svg'), class: 'logo', alt: 'Mastodon'
+          = image_pack_tag 'logo.svg', class: 'logo', alt: 'Mastodon'
 
         = render_navigation
     .content-wrapper

+ 1 - 1
app/views/layouts/auth.html.haml

@@ -6,7 +6,7 @@
     .logo-container
       %h1
         = link_to root_path do
-          = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+          = image_pack_tag 'logo_full.svg', alt: 'Mastodon'
 
     .form-container
       = render 'flashes'

+ 2 - 2
app/views/layouts/mailer.html.haml

@@ -24,7 +24,7 @@
                               %tr
                                 %td.column-cell
                                   = link_to root_url do
-                                    = image_tag full_pack_url('logo_full.png'), alt: 'Mastodon', height: 34, class: 'logo'
+                                    = image_tag full_pack_url('media/images/mailer/logo_full.png'), alt: 'Mastodon', height: 34, class: 'logo'
 
     = yield
 
@@ -49,4 +49,4 @@
                                 %p= link_to t('application_mailer.notification_preferences'), settings_notifications_url
                               %td.column-cell.text-right
                                 = link_to root_url do
-                                  = image_tag full_pack_url('logo_transparent.png'), alt: 'Mastodon', height: 24
+                                  = image_tag full_pack_url('media/images/mailer/logo_transparent.png'), alt: 'Mastodon', height: 24

+ 1 - 1
app/views/layouts/public.html.haml

@@ -8,7 +8,7 @@
         %nav.header
           .nav-left
             = link_to root_url, class: 'brand' do
-              = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon'
+              = image_pack_tag 'logo_full.svg', alt: 'Mastodon'
 
             = link_to t('directories.directory'), explore_path, class: 'nav-link optional' if Setting.profile_directory
             = link_to t('about.about_this'), about_more_path, class: 'nav-link optional'

+ 1 - 1
app/views/notification_mailer/favourite.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_grade.png'), alt:''
+                                      = image_tag full_pack_url('media/images/mailer/icon_grade.png'), alt:''
 
                               %h1= t 'notification_mailer.favourite.title'
                               %p.lead= t('notification_mailer.favourite.body', name: @account.acct)

+ 1 - 1
app/views/notification_mailer/follow.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_person_add.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_person_add.png'), alt: ''
 
                               %h1= t 'notification_mailer.follow.title'
                               %p.lead= t('notification_mailer.follow.body', name: @account.acct)

+ 1 - 1
app/views/notification_mailer/follow_request.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_person_add.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_person_add.png'), alt: ''
 
                               %h1= t 'notification_mailer.follow_request.title'
                               %p.lead= t('notification_mailer.follow_request.body', name: @account.acct)

+ 1 - 1
app/views/notification_mailer/mention.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_reply.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_reply.png'), alt: ''
 
                               %h1= t 'notification_mailer.mention.title'
                               %p.lead= t('notification_mailer.mention.body', name: @status.account.acct)

+ 1 - 1
app/views/notification_mailer/reblog.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_cached.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_cached.png'), alt: ''
 
                               %h1= t 'notification_mailer.reblog.title'
                               %p.lead= t('notification_mailer.reblog.body', name: @account.acct)

+ 1 - 1
app/views/shared/_og.html.haml

@@ -8,7 +8,7 @@
 = opengraph 'og:type', 'website'
 = opengraph 'og:title', @instance_presenter.site_title
 = opengraph 'og:description', description
-= opengraph 'og:image', full_asset_url(thumbnail&.file&.url || asset_pack_path('preview.jpg', protocol: :request))
+= opengraph 'og:image', full_asset_url(thumbnail&.file&.url || asset_pack_path('media/images/preview.jpg', protocol: :request))
 = opengraph 'og:image:width', thumbnail ? thumbnail.meta['width'] : '1200'
 = opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630'
 = opengraph 'twitter:card', 'summary_large_image'

+ 1 - 1
app/views/user_mailer/backup_ready.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_file_download.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_file_download.png'), alt: ''
 
                               %h1= t 'user_mailer.backup_ready.title'
 

+ 1 - 1
app/views/user_mailer/confirmation_instructions.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_email.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_email.png'), alt: ''
 
                               %h1= t 'devise.mailer.confirmation_instructions.title'
 

+ 1 - 1
app/views/user_mailer/email_changed.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_email.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_email.png'), alt: ''
 
                               %h1= t 'devise.mailer.email_changed.title'
                               %p.lead= t 'devise.mailer.email_changed.explanation'

+ 1 - 1
app/views/user_mailer/password_change.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_lock_open.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: ''
 
                               %h1= t 'devise.mailer.password_change.title'
                               %p.lead= t 'devise.mailer.password_change.explanation'

+ 1 - 1
app/views/user_mailer/reconfirmation_instructions.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_email.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_email.png'), alt: ''
 
                               %h1= t 'devise.mailer.reconfirmation_instructions.title'
                               %p.lead= t 'devise.mailer.reconfirmation_instructions.explanation'

+ 1 - 1
app/views/user_mailer/reset_password_instructions.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_lock_open.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: ''
 
                               %h1= t 'devise.mailer.reset_password_instructions.title'
                               %p.lead= t 'devise.mailer.reset_password_instructions.explanation'

+ 1 - 1
app/views/user_mailer/warning.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_warning.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_warning.png'), alt: ''
 
                               %h1= t "user_mailer.warning.title.#{@warning.action}"
 

+ 1 - 1
app/views/user_mailer/welcome.html.haml

@@ -17,7 +17,7 @@
                                 %tbody
                                   %tr
                                     %td
-                                      = image_tag full_pack_url('icon_done.png'), alt: ''
+                                      = image_tag full_pack_url('media/images/mailer/icon_done.png'), alt: ''
 
                               %h1= t 'user_mailer.welcome.title', name: @resource.account.username
                               %p.lead= t 'user_mailer.welcome.explanation'

+ 5 - 1
bin/webpack

@@ -12,4 +12,8 @@ require "bundler/setup"
 
 require "webpacker"
 require "webpacker/webpack_runner"
-Webpacker::WebpackRunner.run(ARGV)
+
+APP_ROOT = File.expand_path("..", __dir__)
+Dir.chdir(APP_ROOT) do
+  Webpacker::WebpackRunner.run(ARGV)
+end

+ 5 - 1
bin/webpack-dev-server

@@ -12,4 +12,8 @@ require "bundler/setup"
 
 require "webpacker"
 require "webpacker/dev_server_runner"
-Webpacker::DevServerRunner.run(ARGV)
+
+APP_ROOT = File.expand_path("..", __dir__)
+Dir.chdir(APP_ROOT) do
+  Webpacker::DevServerRunner.run(ARGV)
+end

+ 1 - 3
config/webpack/configuration.js

@@ -1,12 +1,11 @@
 // Common configuration for webpacker loaded from config/webpacker.yml
 
-const { join, resolve } = require('path');
+const { resolve } = require('path');
 const { env } = require('process');
 const { safeLoad } = require('js-yaml');
 const { readFileSync } = require('fs');
 
 const configPath = resolve('config', 'webpacker.yml');
-const loadersDir = join(__dirname, 'loaders');
 const settings = safeLoad(readFileSync(configPath), 'utf8')[env.RAILS_ENV || env.NODE_ENV];
 
 const themePath = resolve('config', 'themes.yml');
@@ -37,6 +36,5 @@ module.exports = {
     CDN_HOST: env.CDN_HOST,
     NODE_ENV: env.NODE_ENV,
   },
-  loadersDir,
   output,
 };

+ 28 - 12
config/webpack/development.js

@@ -1,12 +1,10 @@
 // Note: You must restart bin/webpack-dev-server for changes to take effect
 
 const merge = require('webpack-merge');
-const sharedConfig = require('./shared.js');
-const { settings, output } = require('./configuration.js');
+const sharedConfig = require('./shared');
+const { settings, output } = require('./configuration');
 
-const watchOptions = {
-  ignored: /node_modules/,
-};
+const watchOptions = {};
 
 if (process.env.VAGRANT) {
   // If we are in Vagrant, we can't rely on inotify to update us with changed
@@ -17,7 +15,7 @@ if (process.env.VAGRANT) {
 
 module.exports = merge(sharedConfig, {
   mode: 'development',
-
+  cache: true,
   devtool: 'cheap-module-eval-source-map',
 
   stats: {
@@ -30,15 +28,33 @@ module.exports = merge(sharedConfig, {
 
   devServer: {
     clientLogLevel: 'none',
-    https: settings.dev_server.https,
+    compress: settings.dev_server.compress,
+    quiet: settings.dev_server.quiet,
+    disableHostCheck: settings.dev_server.disable_host_check,
     host: settings.dev_server.host,
     port: settings.dev_server.port,
+    https: settings.dev_server.https,
+    hot: settings.dev_server.hmr,
     contentBase: output.path,
+    inline: settings.dev_server.inline,
+    useLocalIp: settings.dev_server.use_local_ip,
+    public: settings.dev_server.public,
     publicPath: output.publicPath,
-    compress: true,
-    headers: { 'Access-Control-Allow-Origin': '*' },
-    historyApiFallback: true,
-    disableHostCheck: true,
-    watchOptions: watchOptions,
+    historyApiFallback: {
+      disableDotRule: true,
+    },
+    headers: settings.dev_server.headers,
+    overlay: settings.dev_server.overlay,
+    stats: {
+      entrypoints: false,
+      errorDetails: false,
+      modules: false,
+      moduleTrace: false,
+    },
+    watchOptions: Object.assign(
+      {},
+      settings.dev_server.watch_options,
+      watchOptions
+    ),
   },
 });

+ 0 - 12
config/webpack/loaders/assets.js

@@ -1,12 +0,0 @@
-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]',
-    },
-  }],
-};

+ 0 - 12
config/webpack/loaders/babel.js

@@ -1,12 +0,0 @@
-const { resolve } = require('path');
-
-const env = process.env.NODE_ENV || 'development';
-
-module.exports = {
-  test: /\.js$/,
-  exclude: /node_modules/,
-  loader: 'babel-loader',
-  options: {
-    cacheDirectory: env === 'development' ? false : resolve(__dirname, '..', '..', '..', 'tmp', 'cache', 'babel-loader'),
-  },
-};

+ 0 - 21
config/webpack/loaders/babel_external.js

@@ -1,21 +0,0 @@
-const { resolve } = require('path');
-
-const env = process.env.NODE_ENV || 'development';
-
-if (env === 'development') {
-  module.exports = {};
-} else {
-  // babel options to apply only to external libraries, e.g. remove-prop-types
-  module.exports = {
-    test: /\.js$/,
-    include: /node_modules/,
-    loader: 'babel-loader',
-    options: {
-      babelrc: false,
-      plugins: [
-        'transform-react-remove-prop-types',
-      ],
-      cacheDirectory: env === 'development' ? false : resolve(__dirname, '..', '..', '..', 'tmp', 'cache', 'babel-loader-external'),
-    },
-  };
-}

+ 12 - 16
config/webpack/production.js

@@ -1,15 +1,15 @@
 // Note: You must restart bin/webpack-dev-server for changes to take effect
 
+const path = require('path');
+const { URL } = require('url');
 const merge = require('webpack-merge');
+const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
+const OfflinePlugin = require('offline-plugin');
 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
 const CompressionPlugin = require('compression-webpack-plugin');
 const zopfli = require('@gfx/zopfli');
-const sharedConfig = require('./shared.js');
-const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
-const OfflinePlugin = require('offline-plugin');
-const { publicPath } = require('./configuration.js');
-const path = require('path');
-const { URL } = require('url');
+const { output } = require('./configuration');
+const sharedConfig = require('./shared');
 
 let attachmentHost;
 
@@ -28,15 +28,9 @@ if (process.env.S3_ENABLED === 'true') {
 
 module.exports = merge(sharedConfig, {
   mode: 'production',
-
-  output: {
-    filename: '[name]-[chunkhash].js',
-    chunkFilename: '[name]-[chunkhash].js',
-  },
-
-  devtool: 'source-map', // separate sourcemap file, suitable for production
+  devtool: 'source-map',
   stats: 'normal',
-
+  bail: true,
   optimization: {
     minimize: true,
     minimizer: [
@@ -60,10 +54,12 @@ module.exports = merge(sharedConfig, {
 
   plugins: [
     new CompressionPlugin({
+      filename: '[path].gz[query]',
       algorithm(input, compressionOptions, callback) {
         return zopfli.gzip(input, compressionOptions, callback);
       },
-      test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/,
+      cache: true,
+      test: /\.(js|css|html|json|ico|svg|eot|otf|ttf|map)$/,
     }),
     new BundleAnalyzerPlugin({ // generates report.html and stats.json
       analyzerMode: 'static',
@@ -76,7 +72,7 @@ module.exports = merge(sharedConfig, {
       logLevel: 'silent', // do not bother Webpacker, who runs with --json and parses stdout
     }),
     new OfflinePlugin({
-      publicPath: publicPath, // sw.js must be served from the root to avoid scope issues
+      publicPath: output.publicPath, // sw.js must be served from the root to avoid scope issues
       caches: {
         main: [':rest:'],
         additional: [':externals:'],

+ 21 - 0
config/webpack/rules/babel.js

@@ -0,0 +1,21 @@
+const { join, resolve } = require('path');
+const { env, settings } = require('../configuration');
+
+module.exports = {
+  test: /\.(js|jsx|mjs)$/,
+  include: [
+    settings.source_path,
+    ...settings.resolved_paths,
+  ].map(p => resolve(p)),
+  exclude: /node_modules/,
+  use: [
+    {
+      loader: 'babel-loader',
+      options: {
+        cacheDirectory: join(settings.cache_path, 'babel-loader'),
+        cacheCompression: env.NODE_ENV === 'production',
+        compact: env.NODE_ENV === 'production',
+      },
+    },
+  ],
+};

+ 8 - 1
config/webpack/loaders/sass.js → config/webpack/rules/css.js

@@ -4,7 +4,14 @@ module.exports = {
   test: /\.s?css$/i,
   use: [
     MiniCssExtractPlugin.loader,
-    'css-loader',
+    {
+      loader: 'css-loader',
+      options: {
+        sourceMap: true,
+        importLoaders: 2,
+        localIdentName: '[name]__[local]___[hash:base64:5]',
+      },
+    },
     {
       loader: 'postcss-loader',
       options: {

+ 20 - 0
config/webpack/rules/file.js

@@ -0,0 +1,20 @@
+const { join } = require('path');
+const { settings } = require('../configuration');
+
+module.exports = {
+  test: new RegExp(`(${settings.static_assets_extensions.join('|')})$`, 'i'),
+  use: [
+    {
+      loader: 'file-loader',
+      options: {
+        name(file) {
+          if (file.includes(settings.source_path)) {
+            return 'media/[path][name]-[hash].[ext]';
+          }
+          return 'media/[folder]/[name]-[hash:8].[ext]';
+        },
+        context: join(settings.source_path),
+      },
+    },
+  ],
+};

+ 14 - 0
config/webpack/rules/index.js

@@ -0,0 +1,14 @@
+const babel = require('./babel');
+const css = require('./css');
+const file = require('./file');
+const nodeModules = require('./node_modules');
+
+// Webpack loaders are processed in reverse order
+// https://webpack.js.org/concepts/loaders/#loader-features
+// Lastly, process static files using file loader
+module.exports = {
+  file,
+  css,
+  nodeModules,
+  babel,
+};

+ 0 - 0
config/webpack/loaders/mark.js → config/webpack/rules/mark.js


+ 26 - 0
config/webpack/rules/node_modules.js

@@ -0,0 +1,26 @@
+const { join } = require('path');
+const { settings, env } = require('../configuration');
+
+module.exports = {
+  test: /\.(js|mjs)$/,
+  include: /node_modules/,
+  exclude: /@babel(?:\/|\\{1,2})runtime/,
+  use: [
+    {
+      loader: 'babel-loader',
+      options: {
+        babelrc: false,
+        presets: [
+          ['@babel/env', { modules: false }],
+        ],
+        plugins: [
+          'transform-react-remove-prop-types',
+        ],
+        cacheDirectory: join(settings.cache_path, 'babel-loader-node-modules'),
+        cacheCompression: env.NODE_ENV === 'production',
+        compact: false,
+        sourceMaps: false,
+      },
+    },
+  ],
+};

+ 11 - 6
config/webpack/shared.js

@@ -6,7 +6,8 @@ const { sync } = require('glob');
 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 const AssetsManifestPlugin = require('webpack-assets-manifest');
 const extname = require('path-complete-extname');
-const { env, settings, themes, output, loadersDir } = require('./configuration.js');
+const { env, settings, themes, output } = require('./configuration');
+const rules = require('./rules');
 const localePackPaths = require('./generateLocalePacks');
 
 const extensionGlob = `**/*{${settings.extensions.join(',')}}*`;
@@ -33,8 +34,9 @@ module.exports = {
   ),
 
   output: {
-    filename: '[name].js',
-    chunkFilename: '[name].js',
+    filename: 'js/[name]-[chunkhash].js',
+    chunkFilename: 'js/[name]-[chunkhash].chunk.js',
+    hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js',
     path: output.path,
     publicPath: output.publicPath,
   },
@@ -60,7 +62,7 @@ module.exports = {
   },
 
   module: {
-    rules: sync(join(loadersDir, '*.js')).map(loader => require(loader)),
+    rules: Object.keys(rules).map(key => rules[key]),
   },
 
   plugins: [
@@ -73,11 +75,14 @@ module.exports = {
       }
     ),
     new MiniCssExtractPlugin({
-      filename: env.NODE_ENV === 'production' ? '[name]-[contenthash].css' : '[name].css',
+      filename: 'css/[name]-[contenthash:8].css',
+      chunkFilename: 'css/[name]-[contenthash:8].chunk.css',
     }),
     new AssetsManifestPlugin({
-      publicPath: true,
+      integrity: false,
+      entrypoints: true,
       writeToDisk: true,
+      publicPath: true,
     }),
   ],
 

+ 41 - 4
config/webpacker.yml

@@ -3,8 +3,11 @@
 default: &default
   source_path: app/javascript
   source_entry_path: packs
+  public_root_path: public
   public_output_path: packs
   cache_path: tmp/cache/webpacker
+  check_yarn_integrity: false
+  webpack_compile_output: false
 
   # Additional paths webpack should lookup modules
   # ['app/assets', 'engine/foo/app/assets']
@@ -13,11 +16,31 @@ default: &default
   # Reload manifest.json on all requests so we reload latest compiled packs
   cache_manifest: false
 
+  # Extract and emit a css file
+  extract_css: true
+
+  static_assets_extensions:
+    - .jpg
+    - .jpeg
+    - .png
+    - .tiff
+    - .ico
+    - .svg
+    - .eot
+    - .otf
+    - .ttf
+    - .woff
+    - .woff2
+
   extensions:
+    - .mjs
     - .js
     - .sass
     - .scss
     - .css
+    - .module.sass
+    - .module.scss
+    - .module.css
     - .png
     - .svg
     - .gif
@@ -26,24 +49,38 @@ default: &default
 
 development:
   <<: *default
+
   compile: true
 
+  # Reference: https://webpack.js.org/configuration/dev-server/
   dev_server:
+    https: false
     host: localhost
     port: 3035
+    public: localhost:3035
     hmr: false
-    https: false
+    # Inline should be set to true if using HMR
+    inline: true
+    overlay: true
+    compress: true
+    disable_host_check: true
+    use_local_ip: false
+    quiet: false
+    headers:
+      'Access-Control-Allow-Origin': '*'
+    watch_options:
+      ignored: '**/node_modules/**'
 
 test:
   <<: *default
 
-  # Compile test packs to a separate directory
-  public_output_path: packs-test
-
   # CircleCI precompiles packs prior to running the tests.
   # Also avoids race conditions in parallel_tests.
   compile: false
 
+  # Compile test packs to a separate directory
+  public_output_path: packs-test
+
 production:
   <<: *default
 

+ 0 - 29
jest.config.js

@@ -1,29 +0,0 @@
-module.exports = {
-  projects: [
-    '<rootDir>/app/javascript/mastodon',
-  ],
-  testPathIgnorePatterns: [
-    '<rootDir>/node_modules/',
-    '<rootDir>/vendor/',
-    '<rootDir>/config/',
-    '<rootDir>/log/',
-    '<rootDir>/public/',
-    '<rootDir>/tmp/',
-  ],
-  setupFiles: [
-    'raf/polyfill',
-  ],
-  setupTestFrameworkScriptFile: '<rootDir>/app/javascript/mastodon/test_setup.js',
-  collectCoverageFrom: [
-    'app/javascript/mastodon/**/*.js',
-    '!app/javascript/mastodon/features/emoji/emoji_compressed.js',
-    '!app/javascript/mastodon/locales/locale-data/*.js',
-    '!app/javascript/mastodon/service_worker/entry.js',
-    '!app/javascript/mastodon/test_setup.js',
-  ],
-  coverageDirectory: '<rootDir>/coverage',
-  moduleDirectories: [
-    '<rootDir>/node_modules',
-    '<rootDir>/app/javascript',
-  ],
-};

+ 53 - 27
package.json

@@ -24,36 +24,66 @@
     "iOS >= 9",
     "not dead"
   ],
+  "jest": {
+    "projects": [
+      "<rootDir>/app/javascript/mastodon"
+    ],
+    "testPathIgnorePatterns": [
+      "<rootDir>/node_modules/",
+      "<rootDir>/vendor/",
+      "<rootDir>/config/",
+      "<rootDir>/log/",
+      "<rootDir>/public/",
+      "<rootDir>/tmp/"
+    ],
+    "setupFiles": [
+      "raf/polyfill"
+    ],
+    "setupFilesAfterEnv": [
+      "<rootDir>/app/javascript/mastodon/test_setup.js"
+    ],
+    "collectCoverageFrom": [
+      "app/javascript/mastodon/**/*.js",
+      "!app/javascript/mastodon/features/emoji/emoji_compressed.js",
+      "!app/javascript/mastodon/locales/locale-data/*.js",
+      "!app/javascript/mastodon/service_worker/entry.js",
+      "!app/javascript/mastodon/test_setup.js"
+    ],
+    "coverageDirectory": "<rootDir>/coverage",
+    "moduleDirectories": [
+      "<rootDir>/node_modules",
+      "<rootDir>/app/javascript"
+    ]
+  },
   "private": true,
   "dependencies": {
-    "@babel/core": "^7.2.2",
-    "@babel/plugin-proposal-class-properties": "^7.2.3",
-    "@babel/plugin-proposal-decorators": "^7.2.3",
-    "@babel/plugin-proposal-object-rest-spread": "^7.2.0",
+    "@babel/core": "^7.3.4",
+    "@babel/plugin-proposal-class-properties": "^7.3.4",
+    "@babel/plugin-proposal-decorators": "^7.3.0",
+    "@babel/plugin-proposal-object-rest-spread": "^7.3.4",
     "@babel/plugin-syntax-dynamic-import": "^7.2.0",
     "@babel/plugin-transform-react-inline-elements": "^7.2.0",
     "@babel/plugin-transform-react-jsx-self": "^7.2.0",
     "@babel/plugin-transform-react-jsx-source": "^7.2.0",
-    "@babel/plugin-transform-runtime": "^7.2.0",
-    "@babel/preset-env": "^7.2.3",
+    "@babel/plugin-transform-runtime": "^7.3.4",
+    "@babel/preset-env": "^7.3.4",
     "@babel/preset-react": "^7.0.0",
-    "@babel/runtime": "^7.2.0",
-    "@gfx/zopfli": "^1.0.10",
+    "@babel/runtime": "^7.3.4",
+    "@gfx/zopfli": "^1.0.11",
     "array-includes": "^3.0.3",
-    "autoprefixer": "^9.4.3",
+    "autoprefixer": "^9.4.10",
     "axios": "^0.18.0",
-    "babel-core": "^7.0.0-bridge.0",
-    "babel-loader": "^8.0.4",
+    "babel-loader": "^8.0.5",
     "babel-plugin-lodash": "^3.3.4",
     "babel-plugin-preval": "^3.0.1",
     "babel-plugin-react-intl": "^3.0.1",
-    "babel-plugin-transform-react-remove-prop-types": "^0.4.21",
+    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
     "babel-runtime": "^6.26.0",
     "classnames": "^2.2.5",
     "compression-webpack-plugin": "^2.0.0",
     "cross-env": "^5.1.4",
-    "css-loader": "^2.1.0",
-    "cssnano": "^4.1.8",
+    "css-loader": "^2.1.1",
+    "cssnano": "^4.1.10",
     "detect-passive-events": "^1.0.2",
     "dotenv": "^6.2.0",
     "emoji-mart": "Gargron/emoji-mart#build",
@@ -119,26 +149,25 @@
     "requestidlecallback": "^0.3.0",
     "reselect": "^4.0.0",
     "rimraf": "^2.6.1",
-    "sass": "^1.15.2",
+    "sass": "^1.17.2",
     "sass-loader": "^7.0.3",
     "stringz": "^1.0.0",
-    "style-loader": "0.23.1",
     "substring-trie": "^1.0.2",
     "throng": "^4.0.0",
     "tiny-queue": "^0.2.1",
-    "uglifyjs-webpack-plugin": "^2.1.1",
+    "uglifyjs-webpack-plugin": "^2.1.2",
     "uuid": "^3.1.0",
     "uws": "10.148.0",
-    "webpack": "^4.28.3",
+    "webpack": "^4.29.6",
     "webpack-assets-manifest": "^3.1.1",
-    "webpack-bundle-analyzer": "^3.0.3",
-    "webpack-cli": "^3.1.2",
-    "webpack-merge": "^4.1.5",
+    "webpack-bundle-analyzer": "^3.1.0",
+    "webpack-cli": "^3.2.3",
+    "webpack-merge": "^4.2.1",
     "websocket.js": "^0.1.12"
   },
   "devDependencies": {
     "babel-eslint": "^10.0.1",
-    "babel-jest": "^23.6.0",
+    "babel-jest": "^24.5.0",
     "enzyme": "^3.8.0",
     "enzyme-adapter-react-16": "^1.7.1",
     "eslint": "^5.11.1",
@@ -146,14 +175,11 @@
     "eslint-plugin-jsx-a11y": "~6.1.2",
     "eslint-plugin-promise": "~4.0.1",
     "eslint-plugin-react": "~7.12.1",
-    "jest": "^23.6.0",
+    "jest": "^24.5.0",
     "raf": "^3.4.1",
     "react-intl-translations-manager": "^5.0.3",
     "react-test-renderer": "^16.7.0",
-    "webpack-dev-server": "^3.1.14",
+    "webpack-dev-server": "^3.2.1",
     "yargs": "^12.0.5"
-  },
-  "optionalDependencies": {
-    "fsevents": "*"
   }
 }

File diff suppressed because it is too large
+ 497 - 243
yarn.lock


Some files were not shown because too many files changed in this diff