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>
This commit is contained in:
Yamagishi Kazutoshi 2019-03-15 23:05:31 +09:00 committed by Eugen Rochko
parent 5a9978f02a
commit 8347479f5d
46 changed files with 1655 additions and 1651 deletions

View File

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

View File

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

View File

@ -32,7 +32,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
end end
def thumbnail 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 end
def stats def stats

View File

@ -11,7 +11,7 @@ class RSS::AccountSerializer
builder.title("#{display_name(account)} (@#{account.local_username_and_domain})") builder.title("#{display_name(account)} (@#{account.local_username_and_domain})")
.description(account_description(account)) .description(account_description(account))
.link(TagManager.instance.url_for(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') .accent_color('2b90d9')
builder.image(full_asset_url(account.avatar.url(:original))) if account.avatar? builder.image(full_asset_url(account.avatar.url(:original))) if account.avatar?

View File

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

View File

@ -9,7 +9,7 @@
.column-0 .column-0
.public-account-header.public-account-header--no-bar .public-account-header.public-account-header--no-bar
.public-account-header__image .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 .column-1
.landing-page__call-to-action{ dir: 'ltr' } .landing-page__call-to-action{ dir: 'ltr' }
@ -25,7 +25,7 @@
%span= t 'about.status_count_after', count: @instance_presenter.status_count %span= t 'about.status_count_after', count: @instance_presenter.status_count
.row__mascot .row__mascot
.landing-page__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 .column-2
.landing-page__information.contact-widget .landing-page__information.contact-widget

View File

@ -8,7 +8,7 @@
.landing .landing
.landing__brand .landing__brand
= link_to root_url, class: 'brand' do = 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' %span.brand__tagline=t 'about.tagline'
.landing__grid .landing__grid
@ -48,7 +48,7 @@
.hero-widget .hero-widget
.hero-widget__img .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? - if @instance_presenter.site_short_description.present?
.hero-widget__text .hero-widget__text

View File

@ -1,6 +1,6 @@
.hero-widget .hero-widget
.hero-widget__img .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 .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) %p= @instance_presenter.site_short_description.html_safe.presence || @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname)

View File

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

View File

@ -6,7 +6,7 @@
.sidebar-wrapper .sidebar-wrapper
.sidebar .sidebar
= link_to root_path do = 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 = render_navigation
.content-wrapper .content-wrapper

View File

@ -6,7 +6,7 @@
.logo-container .logo-container
%h1 %h1
= link_to root_path do = 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 .form-container
= render 'flashes' = render 'flashes'

View File

@ -24,7 +24,7 @@
%tr %tr
%td.column-cell %td.column-cell
= link_to root_url do = 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 = yield
@ -49,4 +49,4 @@
%p= link_to t('application_mailer.notification_preferences'), settings_notifications_url %p= link_to t('application_mailer.notification_preferences'), settings_notifications_url
%td.column-cell.text-right %td.column-cell.text-right
= link_to root_url do = 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

View File

@ -8,7 +8,7 @@
%nav.header %nav.header
.nav-left .nav-left
= link_to root_url, class: 'brand' do = 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('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' = link_to t('about.about_this'), about_more_path, class: 'nav-link optional'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'notification_mailer.favourite.title'
%p.lead= t('notification_mailer.favourite.body', name: @account.acct) %p.lead= t('notification_mailer.favourite.body', name: @account.acct)

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'notification_mailer.follow.title'
%p.lead= t('notification_mailer.follow.body', name: @account.acct) %p.lead= t('notification_mailer.follow.body', name: @account.acct)

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'notification_mailer.follow_request.title'
%p.lead= t('notification_mailer.follow_request.body', name: @account.acct) %p.lead= t('notification_mailer.follow_request.body', name: @account.acct)

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'notification_mailer.mention.title'
%p.lead= t('notification_mailer.mention.body', name: @status.account.acct) %p.lead= t('notification_mailer.mention.body', name: @status.account.acct)

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'notification_mailer.reblog.title'
%p.lead= t('notification_mailer.reblog.body', name: @account.acct) %p.lead= t('notification_mailer.reblog.body', name: @account.acct)

View File

@ -8,7 +8,7 @@
= opengraph 'og:type', 'website' = opengraph 'og:type', 'website'
= opengraph 'og:title', @instance_presenter.site_title = opengraph 'og:title', @instance_presenter.site_title
= opengraph 'og:description', description = 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:width', thumbnail ? thumbnail.meta['width'] : '1200'
= opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630' = opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630'
= opengraph 'twitter:card', 'summary_large_image' = opengraph 'twitter:card', 'summary_large_image'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'user_mailer.backup_ready.title'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'devise.mailer.confirmation_instructions.title'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'devise.mailer.email_changed.title'
%p.lead= t 'devise.mailer.email_changed.explanation' %p.lead= t 'devise.mailer.email_changed.explanation'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'devise.mailer.password_change.title'
%p.lead= t 'devise.mailer.password_change.explanation' %p.lead= t 'devise.mailer.password_change.explanation'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'devise.mailer.reconfirmation_instructions.title'
%p.lead= t 'devise.mailer.reconfirmation_instructions.explanation' %p.lead= t 'devise.mailer.reconfirmation_instructions.explanation'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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' %h1= t 'devise.mailer.reset_password_instructions.title'
%p.lead= t 'devise.mailer.reset_password_instructions.explanation' %p.lead= t 'devise.mailer.reset_password_instructions.explanation'

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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}" %h1= t "user_mailer.warning.title.#{@warning.action}"

View File

@ -17,7 +17,7 @@
%tbody %tbody
%tr %tr
%td %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 %h1= t 'user_mailer.welcome.title', name: @resource.account.username
%p.lead= t 'user_mailer.welcome.explanation' %p.lead= t 'user_mailer.welcome.explanation'

View File

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

View File

@ -12,4 +12,8 @@ require "bundler/setup"
require "webpacker" require "webpacker"
require "webpacker/dev_server_runner" 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

View File

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

View File

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

View File

@ -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]',
},
}],
};

View File

@ -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'),
},
};

View File

@ -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'),
},
};
}

View File

@ -1,15 +1,15 @@
// 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 path = require('path');
const { URL } = require('url');
const merge = require('webpack-merge'); const merge = require('webpack-merge');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const OfflinePlugin = require('offline-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin'); const CompressionPlugin = require('compression-webpack-plugin');
const zopfli = require('@gfx/zopfli'); const zopfli = require('@gfx/zopfli');
const sharedConfig = require('./shared.js'); const { output } = require('./configuration');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const sharedConfig = require('./shared');
const OfflinePlugin = require('offline-plugin');
const { publicPath } = require('./configuration.js');
const path = require('path');
const { URL } = require('url');
let attachmentHost; let attachmentHost;
@ -28,15 +28,9 @@ if (process.env.S3_ENABLED === 'true') {
module.exports = merge(sharedConfig, { module.exports = merge(sharedConfig, {
mode: 'production', mode: 'production',
devtool: 'source-map',
output: {
filename: '[name]-[chunkhash].js',
chunkFilename: '[name]-[chunkhash].js',
},
devtool: 'source-map', // separate sourcemap file, suitable for production
stats: 'normal', stats: 'normal',
bail: true,
optimization: { optimization: {
minimize: true, minimize: true,
minimizer: [ minimizer: [
@ -60,10 +54,12 @@ module.exports = merge(sharedConfig, {
plugins: [ plugins: [
new CompressionPlugin({ new CompressionPlugin({
filename: '[path].gz[query]',
algorithm(input, compressionOptions, callback) { algorithm(input, compressionOptions, callback) {
return zopfli.gzip(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 new BundleAnalyzerPlugin({ // generates report.html and stats.json
analyzerMode: 'static', analyzerMode: 'static',
@ -76,7 +72,7 @@ module.exports = merge(sharedConfig, {
logLevel: 'silent', // do not bother Webpacker, who runs with --json and parses stdout logLevel: 'silent', // do not bother Webpacker, who runs with --json and parses stdout
}), }),
new OfflinePlugin({ 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: { caches: {
main: [':rest:'], main: [':rest:'],
additional: [':externals:'], additional: [':externals:'],

View File

@ -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',
},
},
],
};

View File

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

View File

@ -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),
},
},
],
};

View File

@ -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,
};

View File

@ -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,
},
},
],
};

View File

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

View File

@ -3,8 +3,11 @@
default: &default default: &default
source_path: app/javascript source_path: app/javascript
source_entry_path: packs source_entry_path: packs
public_root_path: public
public_output_path: packs public_output_path: packs
cache_path: tmp/cache/webpacker cache_path: tmp/cache/webpacker
check_yarn_integrity: false
webpack_compile_output: false
# Additional paths webpack should lookup modules # Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets'] # ['app/assets', 'engine/foo/app/assets']
@ -13,11 +16,31 @@ default: &default
# Reload manifest.json on all requests so we reload latest compiled packs # Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false 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: extensions:
- .mjs
- .js - .js
- .sass - .sass
- .scss - .scss
- .css - .css
- .module.sass
- .module.scss
- .module.css
- .png - .png
- .svg - .svg
- .gif - .gif
@ -26,24 +49,38 @@ default: &default
development: development:
<<: *default <<: *default
compile: true compile: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server: dev_server:
https: false
host: localhost host: localhost
port: 3035 port: 3035
public: localhost:3035
hmr: false 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: test:
<<: *default <<: *default
# Compile test packs to a separate directory
public_output_path: packs-test
# CircleCI precompiles packs prior to running the tests. # CircleCI precompiles packs prior to running the tests.
# Also avoids race conditions in parallel_tests. # Also avoids race conditions in parallel_tests.
compile: false compile: false
# Compile test packs to a separate directory
public_output_path: packs-test
production: production:
<<: *default <<: *default

View File

@ -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',
],
};

View File

@ -24,36 +24,66 @@
"iOS >= 9", "iOS >= 9",
"not dead" "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, "private": true,
"dependencies": { "dependencies": {
"@babel/core": "^7.2.2", "@babel/core": "^7.3.4",
"@babel/plugin-proposal-class-properties": "^7.2.3", "@babel/plugin-proposal-class-properties": "^7.3.4",
"@babel/plugin-proposal-decorators": "^7.2.3", "@babel/plugin-proposal-decorators": "^7.3.0",
"@babel/plugin-proposal-object-rest-spread": "^7.2.0", "@babel/plugin-proposal-object-rest-spread": "^7.3.4",
"@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-react-inline-elements": "^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-self": "^7.2.0",
"@babel/plugin-transform-react-jsx-source": "^7.2.0", "@babel/plugin-transform-react-jsx-source": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.2.0", "@babel/plugin-transform-runtime": "^7.3.4",
"@babel/preset-env": "^7.2.3", "@babel/preset-env": "^7.3.4",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.2.0", "@babel/runtime": "^7.3.4",
"@gfx/zopfli": "^1.0.10", "@gfx/zopfli": "^1.0.11",
"array-includes": "^3.0.3", "array-includes": "^3.0.3",
"autoprefixer": "^9.4.3", "autoprefixer": "^9.4.10",
"axios": "^0.18.0", "axios": "^0.18.0",
"babel-core": "^7.0.0-bridge.0", "babel-loader": "^8.0.5",
"babel-loader": "^8.0.4",
"babel-plugin-lodash": "^3.3.4", "babel-plugin-lodash": "^3.3.4",
"babel-plugin-preval": "^3.0.1", "babel-plugin-preval": "^3.0.1",
"babel-plugin-react-intl": "^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", "babel-runtime": "^6.26.0",
"classnames": "^2.2.5", "classnames": "^2.2.5",
"compression-webpack-plugin": "^2.0.0", "compression-webpack-plugin": "^2.0.0",
"cross-env": "^5.1.4", "cross-env": "^5.1.4",
"css-loader": "^2.1.0", "css-loader": "^2.1.1",
"cssnano": "^4.1.8", "cssnano": "^4.1.10",
"detect-passive-events": "^1.0.2", "detect-passive-events": "^1.0.2",
"dotenv": "^6.2.0", "dotenv": "^6.2.0",
"emoji-mart": "Gargron/emoji-mart#build", "emoji-mart": "Gargron/emoji-mart#build",
@ -119,26 +149,25 @@
"requestidlecallback": "^0.3.0", "requestidlecallback": "^0.3.0",
"reselect": "^4.0.0", "reselect": "^4.0.0",
"rimraf": "^2.6.1", "rimraf": "^2.6.1",
"sass": "^1.15.2", "sass": "^1.17.2",
"sass-loader": "^7.0.3", "sass-loader": "^7.0.3",
"stringz": "^1.0.0", "stringz": "^1.0.0",
"style-loader": "0.23.1",
"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": "^2.1.1", "uglifyjs-webpack-plugin": "^2.1.2",
"uuid": "^3.1.0", "uuid": "^3.1.0",
"uws": "10.148.0", "uws": "10.148.0",
"webpack": "^4.28.3", "webpack": "^4.29.6",
"webpack-assets-manifest": "^3.1.1", "webpack-assets-manifest": "^3.1.1",
"webpack-bundle-analyzer": "^3.0.3", "webpack-bundle-analyzer": "^3.1.0",
"webpack-cli": "^3.1.2", "webpack-cli": "^3.2.3",
"webpack-merge": "^4.1.5", "webpack-merge": "^4.2.1",
"websocket.js": "^0.1.12" "websocket.js": "^0.1.12"
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0", "babel-jest": "^24.5.0",
"enzyme": "^3.8.0", "enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1", "enzyme-adapter-react-16": "^1.7.1",
"eslint": "^5.11.1", "eslint": "^5.11.1",
@ -146,14 +175,11 @@
"eslint-plugin-jsx-a11y": "~6.1.2", "eslint-plugin-jsx-a11y": "~6.1.2",
"eslint-plugin-promise": "~4.0.1", "eslint-plugin-promise": "~4.0.1",
"eslint-plugin-react": "~7.12.1", "eslint-plugin-react": "~7.12.1",
"jest": "^23.6.0", "jest": "^24.5.0",
"raf": "^3.4.1", "raf": "^3.4.1",
"react-intl-translations-manager": "^5.0.3", "react-intl-translations-manager": "^5.0.3",
"react-test-renderer": "^16.7.0", "react-test-renderer": "^16.7.0",
"webpack-dev-server": "^3.1.14", "webpack-dev-server": "^3.2.1",
"yargs": "^12.0.5" "yargs": "^12.0.5"
},
"optionalDependencies": {
"fsevents": "*"
} }
} }

2852
yarn.lock

File diff suppressed because it is too large Load Diff