Commit 53e42bf9 authored by Yamagishi Kazutoshi's avatar Yamagishi Kazutoshi Committed by Eugen Rochko

Upgrade Webpacker to version 2.0 (#3729)

parent 94d0e012
......@@ -20,6 +20,7 @@ coverage
public/system
public/assets
public/packs
public/packs-test
.env
.env.production
node_modules/
......
......@@ -5,7 +5,7 @@ cache:
directories:
- node_modules
- public/assets
- public/packs
- public/packs-test
dist: trusty
sudo: false
......
......@@ -59,7 +59,7 @@ gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
gem 'statsd-instrument', '~> 2.1'
gem 'twitter-text', '~> 1.14'
gem 'tzinfo-data', '~> 1.2017'
gem 'webpacker', '~> 1.2'
gem 'webpacker', '~> 2.0'
group :development, :test do
gem 'fabrication', '~> 2.16'
......
......@@ -461,7 +461,7 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
webpacker (1.2)
webpacker (2.0)
activesupport (>= 4.2)
multi_json (~> 1.2)
railties (>= 4.2)
......@@ -558,7 +558,7 @@ DEPENDENCIES
tzinfo-data (~> 1.2017)
uglifier (~> 3.2)
webmock (~> 3.0)
webpacker (~> 1.2)
webpacker (~> 2.0)
RUBY VERSION
ruby 2.4.1p111
......
......@@ -5,29 +5,24 @@ require "shellwords"
require "yaml"
ENV["RAILS_ENV"] ||= "development"
RAILS_ENV = ENV["RAILS_ENV"]
RAILS_ENV = ENV["RAILS_ENV"]
ENV["NODE_ENV"] ||= RAILS_ENV
NODE_ENV = ENV["NODE_ENV"]
NODE_ENV = ENV["NODE_ENV"]
APP_PATH = File.expand_path("../", __dir__)
CONFIG_PATH = File.join(APP_PATH, "config/webpack/paths.yml")
APP_PATH = File.expand_path("../", __dir__)
NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
WEBPACK_CONFIG = File.join(APP_PATH, "config/webpack/#{NODE_ENV}.js")
begin
paths = YAML.load(File.read(CONFIG_PATH))[NODE_ENV]
NODE_MODULES_PATH = File.join(APP_PATH.shellescape, paths["node_modules"])
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, paths["config"])
rescue Errno::ENOENT, NoMethodError
puts "Configuration not found in config/webpack/paths.yml"
unless File.exist?(WEBPACK_CONFIG)
puts "Webpack configuration not found."
puts "Please run bundle exec rails webpacker:install to install webpacker"
exit!
end
WEBPACK_BIN = "#{NODE_MODULES_PATH}/.bin/webpack"
WEBPACK_CONFIG = "#{WEBPACK_CONFIG_PATH}/#{NODE_ENV}.js"
newenv = { "NODE_PATH" => NODE_MODULES_PATH.shellescape }
cmdline = ["yarn", "run", "webpack", "--", "--config", WEBPACK_CONFIG] + ARGV
Dir.chdir(APP_PATH) do
exec "NODE_PATH=#{NODE_MODULES_PATH} #{WEBPACK_BIN} --config #{WEBPACK_CONFIG}" \
" #{ARGV.join(" ")}"
exec newenv, *cmdline
end
......@@ -10,24 +10,34 @@ RAILS_ENV = ENV["RAILS_ENV"]
ENV["NODE_ENV"] ||= RAILS_ENV
NODE_ENV = ENV["NODE_ENV"]
APP_PATH = File.expand_path("../", __dir__)
CONFIG_PATH = File.join(APP_PATH, "config/webpack/paths.yml")
APP_PATH = File.expand_path("../", __dir__)
CONFIG_FILE = File.join(APP_PATH, "config/webpacker.yml")
NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
WEBPACK_CONFIG = File.join(APP_PATH, "config/webpack/development.js")
def args(key)
index = ARGV.index(key)
index ? ARGV[index + 1] : nil
end
begin
paths = YAML.load(File.read(CONFIG_PATH))[NODE_ENV]
dev_server = YAML.load_file(CONFIG_FILE)["development"]["dev_server"]
NODE_MODULES_PATH = File.join(APP_PATH.shellescape, paths["node_modules"])
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, paths["config"])
DEV_SERVER_HOST = "http#{"s" if args('--https') || dev_server["https"]}://#{args('--host') || dev_server["host"]}:#{args('--port') || dev_server["port"]}"
WEBPACK_BIN = "#{NODE_MODULES_PATH}/.bin/webpack-dev-server"
DEV_SERVER_CONFIG = "#{WEBPACK_CONFIG_PATH}/development.server.js"
rescue Errno::ENOENT, NoMethodError
puts "Configuration not found in config/webpacker/paths.yml."
puts "Webpack dev_server configuration not found in #{CONFIG_FILE}."
puts "Please run bundle exec rails webpacker:install to install webpacker"
exit!
end
newenv = {
"NODE_PATH" => NODE_MODULES_PATH.shellescape,
"ASSET_HOST" => DEV_SERVER_HOST.shellescape
}.freeze
cmdline = ["yarn", "run", "webpack-dev-server", "--", "--progress", "--color", "--config", WEBPACK_CONFIG] + ARGV
Dir.chdir(APP_PATH) do
exec "NODE_PATH=#{NODE_MODULES_PATH} #{WEBPACK_BIN} --progress --color " \
"--config #{DEV_SERVER_CONFIG} #{ARGV.join(" ")}"
exec newenv, *cmdline
end
#!/usr/bin/env ruby
VENDOR_PATH = File.expand_path('..', __dir__)
Dir.chdir(VENDOR_PATH) do
begin
exec "yarnpkg #{ARGV.join(" ")}"
rescue Errno::ENOENT
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1
end
end
// Common configuration for webpacker loaded from config/webpack/paths.yml
// Common configuration for webpacker loaded from config/webpacker.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 configPath = resolve('config', 'webpacker.yml');
const loadersDir = join(__dirname, 'loaders');
const paths = safeLoad(readFileSync(join(configPath, 'paths.yml'), 'utf8'))[env.NODE_ENV || 'development'];
const devServer = safeLoad(readFileSync(join(configPath, 'development.server.yml'), 'utf8'))[env.NODE_ENV || 'development'];
const settings = safeLoad(readFileSync(configPath), '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://${env.LOCAL_DOMAIN || devServer.host}:${devServer.port}/${paths.entry}/`;
const publicUrl = ifHasCDN ? `${env.CDN_HOST}/${paths.entry}/` : `/${paths.entry}/`;
const publicPath = env.NODE_ENV !== 'production' ? devServerUrl : publicUrl;
function removeOuterSlashes(string) {
return string.replace(/^\/*/, '').replace(/\/*$/, '');
}
function formatPublicPath(host = '', path = '') {
let formattedHost = removeOuterSlashes(host);
if (formattedHost && !/^http/i.test(formattedHost)) {
formattedHost = `//${formattedHost}`;
}
const formattedPath = removeOuterSlashes(path);
return `${formattedHost}/${formattedPath}/`;
}
const output = {
path: resolve('public', settings.public_output_path),
publicPath: formatPublicPath(env.ASSET_HOST, settings.public_output_path),
};
module.exports = {
devServer,
settings,
env,
paths,
loadersDir,
publicUrl,
publicPath,
output,
};
......@@ -2,6 +2,7 @@
const merge = require('webpack-merge');
const sharedConfig = require('./shared.js');
const { settings, output } = require('./configuration.js');
module.exports = merge(sharedConfig, {
devtool: 'cheap-module-eval-source-map',
......@@ -13,4 +14,19 @@ module.exports = merge(sharedConfig, {
output: {
pathinfo: true,
},
devServer: {
clientLogLevel: 'none',
https: settings.dev_server.https,
host: settings.dev_server.host,
port: settings.dev_server.port,
contentBase: output.path,
publicPath: output.publicPath,
compress: true,
headers: { 'Access-Control-Allow-Origin': '*' },
historyApiFallback: true,
watchOptions: {
ignored: /node_modules/,
},
},
});
// Note: You must restart bin/webpack-dev-server for changes to take effect
const { resolve } = require('path');
const { env } = require('process');
const merge = require('webpack-merge');
const devConfig = require('./development.js');
const { devServer, publicPath, paths } = require('./configuration.js');
module.exports = merge(devConfig, {
devServer: {
host: env.LOCAL_DOMAIN ? '0.0.0.0' : devServer.host,
port: devServer.port,
headers: { 'Access-Control-Allow-Origin': '*' },
compress: true,
historyApiFallback: true,
contentBase: resolve(paths.output, paths.entry),
publicPath,
disableHostCheck: true,
},
});
# 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
......@@ -7,7 +7,8 @@ module.exports = {
fallback: 'style-loader',
use: [
{ loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } },
'postcss-loader',
{ loader: 'postcss-loader', options: { sourceMap: true } },
'resolve-url-loader',
'sass-loader',
],
}),
......
......@@ -7,26 +7,27 @@ const sharedConfig = require('./shared.js');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = merge(sharedConfig, {
devtool: 'source-map', // separate sourcemap file, suitable for production
output: { filename: '[name]-[chunkhash].js' },
devtool: 'source-map', // separate sourcemap file, suitable for production
stats: 'normal',
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: true,
sourceMap: true,
mangle: true,
compress: {
warnings: false,
},
output: {
comments: false,
},
sourceMap: true,
}),
new CompressionPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: /\.(js|css|svg|eot|ttf|woff|woff2)$/,
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/,
}),
new BundleAnalyzerPlugin({ // generates report.html and stats.json
analyzerMode: 'static',
......
......@@ -7,21 +7,22 @@ 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 { env, settings, output, loadersDir } = require('./configuration.js');
const localePackPaths = require('./generateLocalePacks');
const extensionGlob = `**/*{${paths.extensions.join(',')}}*`;
const packPaths = sync(join(paths.source, paths.entry, extensionGlob));
const entryPacks = [].concat(packPaths).concat(localePackPaths).filter(path => path !== join(paths.source, paths.entry, 'custom.js'));
const extensionGlob = `**/*{${settings.extensions.join(',')}}*`;
const entryPath = join(settings.source_path, settings.source_entry_path);
const packPaths = sync(join(entryPath, extensionGlob));
const entryPacks = [...packPaths, ...localePackPaths].filter(path => path !== join(entryPath, 'custom.js'));
const customApplicationStyle = resolve(join(paths.source, 'styles/custom.scss'));
const originalApplicationStyle = resolve(join(paths.source, 'styles/application.scss'));
const customApplicationStyle = resolve(join(settings.source_path, 'styles/custom.scss'));
const originalApplicationStyle = resolve(join(settings.source_path, 'styles/application.scss'));
module.exports = {
entry: entryPacks.reduce(
(map, entry) => {
const localMap = map;
let namespace = relative(join(paths.source, paths.entry), dirname(entry));
let namespace = relative(join(entryPath), dirname(entry));
if (namespace === join('..', '..', '..', 'tmp', 'packs')) {
namespace = ''; // generated by generateLocalePacks.js
}
......@@ -33,8 +34,8 @@ module.exports = {
output: {
filename: '[name].js',
chunkFilename: '[name]-[chunkhash].js',
path: resolve(paths.output, paths.entry),
publicPath,
path: output.path,
publicPath: output.publicPath,
},
module: {
......@@ -44,7 +45,10 @@ module.exports = {
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 ManifestPlugin({
publicPath: output.publicPath,
writeToFileEmit: true,
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: (module, count) => {
......@@ -67,15 +71,15 @@ module.exports = {
'mastodon-application-style': existsSync(customApplicationStyle) ?
customApplicationStyle : originalApplicationStyle,
},
extensions: paths.extensions,
extensions: settings.extensions,
modules: [
resolve(paths.source),
resolve(paths.node_modules),
resolve(settings.source_path),
'node_modules',
],
},
resolveLoader: {
modules: [paths.node_modules],
modules: ['node_modules'],
},
node: {
......
# 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
source_path: app/javascript
source_entry_path: packs
public_output_path: packs
extensions:
- .js
- .sass
......@@ -21,9 +18,15 @@ default: &default
development:
<<: *default
dev_server:
host: 0.0.0.0
port: 8080
https: false
test:
<<: *default
manifest: manifest-test.json
public_output_path: packs-test
production:
<<: *default
......@@ -3,8 +3,8 @@
"license": "AGPL-3.0",
"scripts": {
"postversion": "git push --tags",
"build:development": "cross-env NODE_ENV=development yarn webpack -- --config config/webpack/development.js",
"build:production": "cross-env NODE_ENV=production yarn webpack -- --config config/webpack/production.js",
"build:development": "cross-env RAILS_ENV=development ASSET_HOST=http://0.0.0.0:8080 ./bin/webpack",
"build:production": "cross-env RAILS_ENV=production ./bin/webpack",
"manage:translations": "node ./config/webpack/translationRunner.js",
"start": "rimraf ./tmp/streaming && babel ./streaming/index.js --out-dir ./tmp && node ./tmp/streaming/index.js",
"storybook": "cross-env NODE_ENV=test start-storybook -s ./public -p 9001 -c storybook",
......@@ -97,6 +97,7 @@
"redux-thunk": "^2.2.0",
"requestidlecallback": "^0.3.0",
"reselect": "^3.0.1",
"resolve-url-loader": "^2.0.2",
"rimraf": "^2.6.1",
"sass-loader": "^6.0.5",
"stringz": "^0.2.1",
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment