webpacker 1.2 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +93 -9
- data/Gemfile.lock +2 -2
- data/README.md +979 -93
- data/lib/install/angular.rb +2 -2
- data/lib/install/bin/webpack-dev-server.tt +20 -10
- data/lib/install/bin/webpack.tt +10 -15
- data/lib/install/config/.babelrc +13 -1
- data/lib/install/config/loaders/core/sass.js +3 -2
- data/lib/install/config/loaders/installers/elm.js +20 -0
- data/lib/install/config/loaders/installers/vue.js +1 -0
- data/lib/install/config/webpack/configuration.js +22 -13
- data/lib/install/config/webpack/development.js +17 -1
- data/lib/install/config/webpack/production.js +16 -2
- data/lib/install/config/webpack/shared.js +15 -11
- data/lib/install/config/{webpack/paths.yml → webpacker.yml} +12 -7
- data/lib/install/elm.rb +29 -0
- data/lib/install/examples/angular/tsconfig.json +1 -0
- data/lib/install/examples/elm/Main.elm +54 -0
- data/lib/install/examples/elm/hello_elm.js +11 -0
- data/lib/install/examples/vue/hello_vue.js +4 -8
- data/lib/install/react.rb +2 -2
- data/lib/install/template.rb +10 -11
- data/lib/install/vue.rb +2 -2
- data/lib/tasks/installers.rake +1 -0
- data/lib/tasks/webpacker.rake +11 -9
- data/lib/tasks/webpacker/check_webpack_binstubs.rake +11 -0
- data/lib/tasks/webpacker/check_yarn.rake +6 -3
- data/lib/tasks/webpacker/clobber.rake +3 -3
- data/lib/tasks/webpacker/compile.rake +14 -20
- data/lib/tasks/webpacker/verify_install.rake +2 -2
- data/lib/tasks/webpacker/yarn_install.rake +2 -2
- data/lib/webpacker.rb +16 -1
- data/lib/webpacker/compiler.rb +20 -0
- data/lib/webpacker/configuration.rb +30 -22
- data/lib/webpacker/env.rb +2 -6
- data/lib/webpacker/helper.rb +0 -2
- data/lib/webpacker/manifest.rb +23 -6
- data/lib/webpacker/version.rb +1 -1
- data/package.json +1 -1
- data/test/configuration_test.rb +32 -0
- data/test/env_test.rb +3 -5
- data/test/helper_test.rb +23 -0
- data/test/manifest_test.rb +30 -0
- data/test/test_app/config/secrets.yml +5 -0
- data/test/test_app/public/packs/manifest.json +4 -0
- data/test/webpacker_test.rb +2 -1
- metadata +20 -7
- data/lib/install/bin/yarn.tt +0 -11
- data/lib/install/config/webpack/development.server.js +0 -17
- data/lib/install/config/webpack/development.server.yml +0 -17
data/lib/install/angular.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "webpacker/configuration"
|
2
2
|
|
3
|
-
puts "Copying angular loader to
|
3
|
+
puts "Copying angular loader to config/webpack/loaders"
|
4
4
|
copy_file "#{__dir__}/config/loaders/installers/angular.js", "config/webpack/loaders/angular.js"
|
5
5
|
|
6
6
|
puts "Copying angular example entry file to #{Webpacker::Configuration.entry_path}"
|
@@ -13,6 +13,6 @@ puts "Copying tsconfig.json to the Rails root directory for typescript"
|
|
13
13
|
copy_file "#{__dir__}/examples/angular/tsconfig.json", "tsconfig.json"
|
14
14
|
|
15
15
|
puts "Installing all angular dependencies"
|
16
|
-
run "
|
16
|
+
run "yarn add typescript ts-loader core-js zone.js rxjs @angular/core @angular/common @angular/compiler @angular/platform-browser @angular/platform-browser-dynamic"
|
17
17
|
|
18
18
|
puts "Webpacker now supports angular and typescript 🎉"
|
@@ -10,24 +10,34 @@ RAILS_ENV = ENV["RAILS_ENV"]
|
|
10
10
|
ENV["NODE_ENV"] ||= RAILS_ENV
|
11
11
|
NODE_ENV = ENV["NODE_ENV"]
|
12
12
|
|
13
|
-
APP_PATH
|
14
|
-
|
13
|
+
APP_PATH = File.expand_path("../", __dir__)
|
14
|
+
CONFIG_FILE = File.join(APP_PATH, "config/webpacker.yml")
|
15
|
+
NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
|
16
|
+
WEBPACK_CONFIG = File.join(APP_PATH, "config/webpack/development.js")
|
17
|
+
|
18
|
+
def args(key)
|
19
|
+
index = ARGV.index(key)
|
20
|
+
index ? ARGV[index + 1] : nil
|
21
|
+
end
|
15
22
|
|
16
23
|
begin
|
17
|
-
|
24
|
+
dev_server = YAML.load_file(CONFIG_FILE)["development"]["dev_server"]
|
18
25
|
|
19
|
-
|
20
|
-
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, paths["config"])
|
26
|
+
DEV_SERVER_HOST = "http#{"s" if args('--https') || dev_server["https"]}://#{args('--host') || dev_server["host"]}:#{args('--port') || dev_server["port"]}"
|
21
27
|
|
22
|
-
WEBPACK_BIN = "#{NODE_MODULES_PATH}/.bin/webpack-dev-server"
|
23
|
-
DEV_SERVER_CONFIG = "#{WEBPACK_CONFIG_PATH}/development.server.js"
|
24
28
|
rescue Errno::ENOENT, NoMethodError
|
25
|
-
puts "
|
29
|
+
puts "Webpack dev_server configuration not found in #{CONFIG_FILE}."
|
26
30
|
puts "Please run bundle exec rails webpacker:install to install webpacker"
|
27
31
|
exit!
|
28
32
|
end
|
29
33
|
|
34
|
+
newenv = {
|
35
|
+
"NODE_PATH" => NODE_MODULES_PATH.shellescape,
|
36
|
+
"ASSET_HOST" => DEV_SERVER_HOST.shellescape
|
37
|
+
}.freeze
|
38
|
+
|
39
|
+
cmdline = ["yarn", "run", "webpack-dev-server", "--", "--progress", "--color", "--config", WEBPACK_CONFIG] + ARGV
|
40
|
+
|
30
41
|
Dir.chdir(APP_PATH) do
|
31
|
-
exec
|
32
|
-
"--config #{DEV_SERVER_CONFIG} #{ARGV.join(" ")}"
|
42
|
+
exec newenv, *cmdline
|
33
43
|
end
|
data/lib/install/bin/webpack.tt
CHANGED
@@ -5,29 +5,24 @@ require "shellwords"
|
|
5
5
|
require "yaml"
|
6
6
|
|
7
7
|
ENV["RAILS_ENV"] ||= "development"
|
8
|
-
RAILS_ENV
|
8
|
+
RAILS_ENV = ENV["RAILS_ENV"]
|
9
9
|
|
10
10
|
ENV["NODE_ENV"] ||= RAILS_ENV
|
11
|
-
NODE_ENV
|
11
|
+
NODE_ENV = ENV["NODE_ENV"]
|
12
12
|
|
13
|
-
APP_PATH
|
14
|
-
|
13
|
+
APP_PATH = File.expand_path("../", __dir__)
|
14
|
+
NODE_MODULES_PATH = File.join(APP_PATH, "node_modules")
|
15
|
+
WEBPACK_CONFIG = File.join(APP_PATH, "config/webpack/#{NODE_ENV}.js")
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
NODE_MODULES_PATH = File.join(APP_PATH.shellescape, paths["node_modules"])
|
20
|
-
WEBPACK_CONFIG_PATH = File.join(APP_PATH.shellescape, paths["config"])
|
21
|
-
rescue Errno::ENOENT, NoMethodError
|
22
|
-
puts "Configuration not found in config/webpack/paths.yml"
|
17
|
+
unless File.exist?(WEBPACK_CONFIG)
|
18
|
+
puts "Webpack configuration not found."
|
23
19
|
puts "Please run bundle exec rails webpacker:install to install webpacker"
|
24
20
|
exit!
|
25
21
|
end
|
26
22
|
|
27
|
-
|
28
|
-
|
23
|
+
newenv = { "NODE_PATH" => NODE_MODULES_PATH.shellescape }
|
24
|
+
cmdline = ["yarn", "run", "webpack", "--", "--config", WEBPACK_CONFIG] + ARGV
|
29
25
|
|
30
26
|
Dir.chdir(APP_PATH) do
|
31
|
-
exec
|
32
|
-
" #{ARGV.join(" ")}"
|
27
|
+
exec newenv, *cmdline
|
33
28
|
end
|
data/lib/install/config/.babelrc
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
{
|
2
2
|
"presets": [
|
3
|
-
["env", {
|
3
|
+
["env", {
|
4
|
+
"modules": false,
|
5
|
+
"targets": {
|
6
|
+
"browsers": "> 1%",
|
7
|
+
"uglify": true
|
8
|
+
},
|
9
|
+
"useBuiltIns": true
|
10
|
+
}]
|
11
|
+
],
|
12
|
+
|
13
|
+
"plugins": [
|
14
|
+
"syntax-dynamic-import",
|
15
|
+
["transform-class-properties", { "spec": true }]
|
4
16
|
]
|
5
17
|
}
|
@@ -7,8 +7,9 @@ module.exports = {
|
|
7
7
|
fallback: 'style-loader',
|
8
8
|
use: [
|
9
9
|
{ loader: 'css-loader', options: { minimize: env.NODE_ENV === 'production' } },
|
10
|
-
'postcss-loader',
|
11
|
-
'
|
10
|
+
{ loader: 'postcss-loader', options: { sourceMap: true } },
|
11
|
+
'resolve-url-loader',
|
12
|
+
{ loader: 'sass-loader', options: { sourceMap: true } }
|
12
13
|
]
|
13
14
|
})
|
14
15
|
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
const path = require('path')
|
2
|
+
const { env } = require('../configuration.js')
|
3
|
+
|
4
|
+
const elmSource = path.resolve(process.cwd())
|
5
|
+
const elmMake = `${elmSource}/node_modules/.bin/elm-make`
|
6
|
+
const elmDefaultOptions = `cwd=${elmSource}&pathToMake=${elmMake}`
|
7
|
+
|
8
|
+
const loaderOptions = () => {
|
9
|
+
if (env.NODE_ENV === 'production') {
|
10
|
+
return `elm-webpack-loader?${elmDefaultOptions}`
|
11
|
+
}
|
12
|
+
|
13
|
+
return `elm-hot-loader!elm-webpack-loader?${elmDefaultOptions}&verbose=true&warn=true&debug=true`
|
14
|
+
}
|
15
|
+
|
16
|
+
module.exports = {
|
17
|
+
test: /\.elm$/,
|
18
|
+
exclude: [/elm-stuff/, /node_modules/],
|
19
|
+
loader: loaderOptions()
|
20
|
+
}
|
@@ -1,26 +1,35 @@
|
|
1
|
-
// Common configuration for webpacker loaded from config/
|
1
|
+
// Common configuration for webpacker loaded from config/webpacker.yml
|
2
2
|
|
3
3
|
const { join, resolve } = require('path')
|
4
4
|
const { env } = require('process')
|
5
5
|
const { safeLoad } = require('js-yaml')
|
6
6
|
const { readFileSync } = require('fs')
|
7
7
|
|
8
|
-
const configPath = resolve('config', '
|
8
|
+
const configPath = resolve('config', 'webpacker.yml')
|
9
9
|
const loadersDir = join(__dirname, 'loaders')
|
10
|
-
const
|
11
|
-
const devServer = safeLoad(readFileSync(join(configPath, 'development.server.yml'), 'utf8'))[env.NODE_ENV]
|
10
|
+
const settings = safeLoad(readFileSync(configPath), 'utf8')[env.NODE_ENV]
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
function removeOuterSlashes(string) {
|
13
|
+
return string.replace(/^\/*/, '').replace(/\/*$/, '')
|
14
|
+
}
|
15
|
+
|
16
|
+
function formatPublicPath(host = '', path = '') {
|
17
|
+
let formattedHost = removeOuterSlashes(host)
|
18
|
+
if (formattedHost && !/^http/i.test(formattedHost)) {
|
19
|
+
formattedHost = `//${formattedHost}`
|
20
|
+
}
|
21
|
+
const formattedPath = removeOuterSlashes(path)
|
22
|
+
return `${formattedHost}/${formattedPath}/`
|
23
|
+
}
|
24
|
+
|
25
|
+
const output = {
|
26
|
+
path: resolve('public', settings.public_output_path),
|
27
|
+
publicPath: formatPublicPath(env.ASSET_HOST, settings.public_output_path)
|
28
|
+
}
|
18
29
|
|
19
30
|
module.exports = {
|
20
|
-
|
31
|
+
settings,
|
21
32
|
env,
|
22
|
-
paths,
|
23
33
|
loadersDir,
|
24
|
-
|
25
|
-
publicPath
|
34
|
+
output
|
26
35
|
}
|
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
const merge = require('webpack-merge')
|
4
4
|
const sharedConfig = require('./shared.js')
|
5
|
+
const { settings, output } = require('./configuration.js')
|
5
6
|
|
6
7
|
module.exports = merge(sharedConfig, {
|
7
|
-
devtool: '
|
8
|
+
devtool: 'cheap-eval-source-map',
|
8
9
|
|
9
10
|
stats: {
|
10
11
|
errorDetails: true
|
@@ -12,5 +13,20 @@ module.exports = merge(sharedConfig, {
|
|
12
13
|
|
13
14
|
output: {
|
14
15
|
pathinfo: true
|
16
|
+
},
|
17
|
+
|
18
|
+
devServer: {
|
19
|
+
clientLogLevel: 'none',
|
20
|
+
https: settings.dev_server.https,
|
21
|
+
host: settings.dev_server.host,
|
22
|
+
port: settings.dev_server.port,
|
23
|
+
contentBase: output.path,
|
24
|
+
publicPath: output.publicPath,
|
25
|
+
compress: true,
|
26
|
+
headers: { 'Access-Control-Allow-Origin': '*' },
|
27
|
+
historyApiFallback: true,
|
28
|
+
watchOptions: {
|
29
|
+
ignored: /node_modules/
|
30
|
+
}
|
15
31
|
}
|
16
32
|
})
|
@@ -9,13 +9,27 @@ const sharedConfig = require('./shared.js')
|
|
9
9
|
|
10
10
|
module.exports = merge(sharedConfig, {
|
11
11
|
output: { filename: '[name]-[chunkhash].js' },
|
12
|
+
devtool: 'source-map',
|
13
|
+
stats: 'normal',
|
12
14
|
|
13
15
|
plugins: [
|
14
|
-
new webpack.optimize.UglifyJsPlugin(
|
16
|
+
new webpack.optimize.UglifyJsPlugin({
|
17
|
+
minimize: true,
|
18
|
+
sourceMap: true,
|
19
|
+
|
20
|
+
compress: {
|
21
|
+
warnings: false
|
22
|
+
},
|
23
|
+
|
24
|
+
output: {
|
25
|
+
comments: false
|
26
|
+
}
|
27
|
+
}),
|
28
|
+
|
15
29
|
new CompressionPlugin({
|
16
30
|
asset: '[path].gz[query]',
|
17
31
|
algorithm: 'gzip',
|
18
|
-
test: /\.(js|css|svg|eot|ttf
|
32
|
+
test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
|
19
33
|
})
|
20
34
|
]
|
21
35
|
})
|
@@ -9,16 +9,17 @@ const { sync } = require('glob')
|
|
9
9
|
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
10
10
|
const ManifestPlugin = require('webpack-manifest-plugin')
|
11
11
|
const extname = require('path-complete-extname')
|
12
|
-
const { env,
|
12
|
+
const { env, settings, output, loadersDir } = require('./configuration.js')
|
13
13
|
|
14
|
-
const extensionGlob = `**/*{${
|
15
|
-
const
|
14
|
+
const extensionGlob = `**/*{${settings.extensions.join(',')}}*`
|
15
|
+
const entryPath = join(settings.source_path, settings.source_entry_path)
|
16
|
+
const packPaths = sync(join(entryPath, extensionGlob))
|
16
17
|
|
17
18
|
module.exports = {
|
18
19
|
entry: packPaths.reduce(
|
19
20
|
(map, entry) => {
|
20
21
|
const localMap = map
|
21
|
-
const namespace = relative(join(
|
22
|
+
const namespace = relative(join(entryPath), dirname(entry))
|
22
23
|
localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry)
|
23
24
|
return localMap
|
24
25
|
}, {}
|
@@ -26,8 +27,8 @@ module.exports = {
|
|
26
27
|
|
27
28
|
output: {
|
28
29
|
filename: '[name].js',
|
29
|
-
path:
|
30
|
-
publicPath
|
30
|
+
path: output.path,
|
31
|
+
publicPath: output.publicPath
|
31
32
|
},
|
32
33
|
|
33
34
|
module: {
|
@@ -37,18 +38,21 @@ module.exports = {
|
|
37
38
|
plugins: [
|
38
39
|
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
|
39
40
|
new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
|
40
|
-
new ManifestPlugin({
|
41
|
+
new ManifestPlugin({
|
42
|
+
publicPath: output.publicPath,
|
43
|
+
writeToFileEmit: true
|
44
|
+
})
|
41
45
|
],
|
42
46
|
|
43
47
|
resolve: {
|
44
|
-
extensions:
|
48
|
+
extensions: settings.extensions,
|
45
49
|
modules: [
|
46
|
-
resolve(
|
47
|
-
|
50
|
+
resolve(settings.source_path),
|
51
|
+
'node_modules'
|
48
52
|
]
|
49
53
|
},
|
50
54
|
|
51
55
|
resolveLoader: {
|
52
|
-
modules: [
|
56
|
+
modules: ['node_modules']
|
53
57
|
}
|
54
58
|
}
|
@@ -1,14 +1,13 @@
|
|
1
1
|
# Note: You must restart bin/webpack-dev-server for changes to take effect
|
2
2
|
|
3
3
|
default: &default
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
node_modules: node_modules
|
9
|
-
source: app/javascript
|
4
|
+
source_path: app/javascript
|
5
|
+
source_entry_path: packs
|
6
|
+
public_output_path: packs
|
7
|
+
|
10
8
|
extensions:
|
11
9
|
- .coffee
|
10
|
+
- .erb
|
12
11
|
- .js
|
13
12
|
- .jsx
|
14
13
|
- .ts
|
@@ -25,9 +24,15 @@ default: &default
|
|
25
24
|
development:
|
26
25
|
<<: *default
|
27
26
|
|
27
|
+
dev_server:
|
28
|
+
host: 0.0.0.0
|
29
|
+
port: 8080
|
30
|
+
https: false
|
31
|
+
|
28
32
|
test:
|
29
33
|
<<: *default
|
30
|
-
|
34
|
+
|
35
|
+
public_output_path: packs-test
|
31
36
|
|
32
37
|
production:
|
33
38
|
<<: *default
|
data/lib/install/elm.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "webpacker/configuration"
|
2
|
+
|
3
|
+
puts "Copying elm loader to config/webpack/loaders"
|
4
|
+
copy_file "#{__dir__}/config/loaders/installers/elm.js",
|
5
|
+
"config/webpack/loaders/elm.js"
|
6
|
+
|
7
|
+
puts "Copying elm example entry file to #{Webpacker::Configuration.entry_path}"
|
8
|
+
copy_file "#{__dir__}/examples/elm/Main.elm", "#{Webpacker::Configuration.entry_path}/Main.elm"
|
9
|
+
|
10
|
+
puts "Copying elm app file to #{Webpacker::Configuration.entry_path}"
|
11
|
+
copy_file "#{__dir__}/examples/elm/hello_elm.js",
|
12
|
+
"#{Webpacker::Configuration.entry_path}/hello_elm.js"
|
13
|
+
|
14
|
+
puts "Installing all elm dependencies"
|
15
|
+
run "yarn add elm elm-webpack-loader"
|
16
|
+
run "yarn add --dev elm-hot-loader"
|
17
|
+
run "yarn run elm package install -- --yes"
|
18
|
+
|
19
|
+
puts "Updating Webpack paths to include Elm file extension"
|
20
|
+
insert_into_file Webpacker::Configuration.file_path, " - .elm\n", after: /extensions:\n/
|
21
|
+
|
22
|
+
puts "Updating elm source location"
|
23
|
+
source_path = File.join(Webpacker::Configuration.source, Webpacker::Configuration.fetch(:source_entry_path))
|
24
|
+
gsub_file "elm-package.json", /\"\.\"\n/, %("#{source_path}"\n)
|
25
|
+
|
26
|
+
puts "Updating .gitignore to include elm-stuff folder"
|
27
|
+
insert_into_file ".gitignore", "/elm-stuff\n", before: "/node_modules\n"
|
28
|
+
|
29
|
+
puts "Webpacker now supports elm 🎉"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Main exposing (..)
|
2
|
+
|
3
|
+
import Html exposing (Html, h1, text)
|
4
|
+
import Html.Attributes exposing (style)
|
5
|
+
|
6
|
+
-- MODEL
|
7
|
+
|
8
|
+
type alias Model =
|
9
|
+
{
|
10
|
+
}
|
11
|
+
|
12
|
+
-- INIT
|
13
|
+
|
14
|
+
init : (Model, Cmd Message)
|
15
|
+
init =
|
16
|
+
(Model, Cmd.none)
|
17
|
+
|
18
|
+
-- VIEW
|
19
|
+
|
20
|
+
view : Model -> Html Message
|
21
|
+
view model =
|
22
|
+
-- The inline style is being used for example purposes in order to keep this example simple and
|
23
|
+
-- avoid loading additional resources. Use a proper stylesheet when building your own app.
|
24
|
+
h1 [style [("display", "flex"), ("justify-content", "center")]]
|
25
|
+
[text "Hello Elm!"]
|
26
|
+
|
27
|
+
-- MESSAGE
|
28
|
+
|
29
|
+
type Message
|
30
|
+
= None
|
31
|
+
|
32
|
+
-- UPDATE
|
33
|
+
|
34
|
+
update : Message -> Model -> (Model, Cmd Message)
|
35
|
+
update message model =
|
36
|
+
(model, Cmd.none)
|
37
|
+
|
38
|
+
-- SUBSCRIPTIONS
|
39
|
+
|
40
|
+
subscriptions : Model -> Sub Message
|
41
|
+
subscriptions model =
|
42
|
+
Sub.none
|
43
|
+
|
44
|
+
-- MAIN
|
45
|
+
|
46
|
+
main : Program Never Model Message
|
47
|
+
main =
|
48
|
+
Html.program
|
49
|
+
{
|
50
|
+
init = init,
|
51
|
+
view = view,
|
52
|
+
update = update,
|
53
|
+
subscriptions = subscriptions
|
54
|
+
}
|