webpacker-for-component 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +14 -0
  3. data/.gitignore +6 -0
  4. data/.rubocop.yml +124 -0
  5. data/.travis.yml +22 -0
  6. data/Gemfile +13 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +325 -0
  9. data/Rakefile +12 -0
  10. data/docs/assets.md +106 -0
  11. data/docs/css.md +82 -0
  12. data/docs/deployment.md +39 -0
  13. data/docs/env.md +65 -0
  14. data/docs/es6.md +53 -0
  15. data/docs/folder-structure.md +66 -0
  16. data/docs/misc.md +23 -0
  17. data/docs/props.md +105 -0
  18. data/docs/testing.md +45 -0
  19. data/docs/troubleshooting.md +65 -0
  20. data/docs/typescript.md +116 -0
  21. data/docs/webpack-dev-server.md +32 -0
  22. data/docs/webpack.md +156 -0
  23. data/docs/yarn.md +12 -0
  24. data/lib/install/angular.rb +15 -0
  25. data/lib/install/bin/webpack-dev-server.tt +68 -0
  26. data/lib/install/bin/webpack.tt +30 -0
  27. data/lib/install/config/.babelrc +18 -0
  28. data/lib/install/config/.postcssrc.yml +3 -0
  29. data/lib/install/config/webpack/development.js +3 -0
  30. data/lib/install/config/webpack/environment.js +3 -0
  31. data/lib/install/config/webpack/production.js +3 -0
  32. data/lib/install/config/webpack/test.js +3 -0
  33. data/lib/install/config/webpacker.yml +56 -0
  34. data/lib/install/elm.rb +24 -0
  35. data/lib/install/examples/angular/hello_angular.js +7 -0
  36. data/lib/install/examples/angular/hello_angular/app/app.component.ts +9 -0
  37. data/lib/install/examples/angular/hello_angular/app/app.module.ts +16 -0
  38. data/lib/install/examples/angular/hello_angular/index.ts +8 -0
  39. data/lib/install/examples/angular/hello_angular/polyfills.ts +73 -0
  40. data/lib/install/examples/angular/tsconfig.json +19 -0
  41. data/lib/install/examples/elm/Main.elm +54 -0
  42. data/lib/install/examples/elm/hello_elm.js +11 -0
  43. data/lib/install/examples/react/.babelrc +6 -0
  44. data/lib/install/examples/react/hello_react.jsx +26 -0
  45. data/lib/install/examples/vue/app.vue +22 -0
  46. data/lib/install/examples/vue/hello_vue.js +44 -0
  47. data/lib/install/javascript/packs/application.js +10 -0
  48. data/lib/install/react.rb +28 -0
  49. data/lib/install/template.rb +35 -0
  50. data/lib/install/vue.rb +12 -0
  51. data/lib/tasks/installers.rake +22 -0
  52. data/lib/tasks/webpacker-for-component/check_binstubs.rake +12 -0
  53. data/lib/tasks/webpacker-for-component/check_node.rake +25 -0
  54. data/lib/tasks/webpacker-for-component/check_yarn.rake +24 -0
  55. data/lib/tasks/webpacker-for-component/clobber.rake +16 -0
  56. data/lib/tasks/webpacker-for-component/compile.rake +34 -0
  57. data/lib/tasks/webpacker-for-component/install.rake +13 -0
  58. data/lib/tasks/webpacker-for-component/verify_install.rake +16 -0
  59. data/lib/tasks/webpacker-for-component/yarn_install.rake +6 -0
  60. data/lib/tasks/webpacker.rake +19 -0
  61. data/lib/webpacker-for-component.rb +28 -0
  62. data/lib/webpacker-for-component/commands.rb +23 -0
  63. data/lib/webpacker-for-component/compiler.rb +78 -0
  64. data/lib/webpacker-for-component/configuration.rb +88 -0
  65. data/lib/webpacker-for-component/dev_server.rb +51 -0
  66. data/lib/webpacker-for-component/dev_server_proxy.rb +25 -0
  67. data/lib/webpacker-for-component/helper.rb +65 -0
  68. data/lib/webpacker-for-component/instance.rb +44 -0
  69. data/lib/webpacker-for-component/manifest.rb +79 -0
  70. data/lib/webpacker-for-component/railtie.rb +41 -0
  71. data/lib/webpacker-for-component/version.rb +4 -0
  72. data/package.json +62 -0
  73. data/package/asset_host.js +21 -0
  74. data/package/config.js +8 -0
  75. data/package/environment.js +95 -0
  76. data/package/environments/development.js +46 -0
  77. data/package/environments/production.js +34 -0
  78. data/package/environments/test.js +3 -0
  79. data/package/index.js +16 -0
  80. data/package/loaders/babel.js +11 -0
  81. data/package/loaders/coffee.js +4 -0
  82. data/package/loaders/elm.js +19 -0
  83. data/package/loaders/erb.js +9 -0
  84. data/package/loaders/file.js +15 -0
  85. data/package/loaders/style.js +31 -0
  86. data/package/loaders/typescript.js +4 -0
  87. data/package/loaders/vue.js +12 -0
  88. data/test/command_test.rb +27 -0
  89. data/test/compiler_test.rb +20 -0
  90. data/test/configuration_test.rb +56 -0
  91. data/test/dev_server_test.rb +24 -0
  92. data/test/helper_test.rb +39 -0
  93. data/test/manifest_test.rb +20 -0
  94. data/test/test_app/config/secrets.yml +5 -0
  95. data/test/webpacker_test_helper.rb +40 -0
  96. data/webpacker-for-component.gemspec +23 -0
  97. data/yarn.lock +5162 -0
  98. metadata +111 -7
@@ -0,0 +1,41 @@
1
+ require "rails/railtie"
2
+
3
+ require "webpacker-for-component/helper"
4
+ require "webpacker-for-component/dev_server_proxy"
5
+
6
+ class Webpacker::Engine < ::Rails::Engine
7
+ initializer "webpacker.proxy" do |app|
8
+ if Rails.env.development?
9
+ app.middleware.insert_before 0,
10
+ Rails::VERSION::MAJOR >= 5 ?
11
+ Webpacker::DevServerProxy : "Webpacker::DevServerProxy", ssl_verify_none: true
12
+ end
13
+ end
14
+
15
+ initializer "webpacker.helper" do |app|
16
+ ActiveSupport.on_load :action_controller do
17
+ ActionController::Base.helper Webpacker::Helper
18
+ end
19
+
20
+ ActiveSupport.on_load :action_view do
21
+ include Webpacker::Helper
22
+ end
23
+ end
24
+
25
+ initializer "webpacker.logger" do
26
+ config.after_initialize do |app|
27
+ if ::Rails.logger.respond_to?(:tagged)
28
+ Webpacker.logger = ::Rails.logger
29
+ else
30
+ Webpacker.logger = ActiveSupport::TaggedLogging.new(::Rails.logger)
31
+ end
32
+ end
33
+ end
34
+
35
+ initializer "webpacker.bootstrap" do
36
+ if defined?(Rails::Server) || defined?(Rails::Console)
37
+ Webpacker.bootstrap
38
+ Spring.after_fork { Webpacker.bootstrap } if defined?(Spring)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,4 @@
1
+ module Webpacker
2
+ # Change the version in package.json too, please!
3
+ VERSION = "1.1.0"
4
+ end
data/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "webpacker-for-component",
3
+ "version": "1.1.0",
4
+ "description": "Use Webpack to manage app-like JavaScript modules for component-based use",
5
+ "main": "package/index.js",
6
+ "files": [
7
+ "package"
8
+ ],
9
+ "engines": {
10
+ "node": ">=6.0.0",
11
+ "yarn": ">=0.25.2"
12
+ },
13
+ "dependencies": {
14
+ "babel-core": "^6.26.0",
15
+ "babel-loader": "^7.1.2",
16
+ "babel-plugin-syntax-dynamic-import": "^6.18.0",
17
+ "babel-plugin-transform-class-properties": "^6.24.1",
18
+ "babel-plugin-transform-object-rest-spread": "^6.26.0",
19
+ "babel-polyfill": "^6.26.0",
20
+ "babel-preset-env": "^1.6.0",
21
+ "coffee-loader": "^0.8.0",
22
+ "coffeescript": "^1.12.7",
23
+ "compression-webpack-plugin": "^1.0.0",
24
+ "css-loader": "^0.28.5",
25
+ "extract-text-webpack-plugin": "^3.0.0",
26
+ "file-loader": "^0.11.2",
27
+ "glob": "^7.1.2",
28
+ "js-yaml": "^3.9.1",
29
+ "node-sass": "^4.5.3",
30
+ "path-complete-extname": "^0.1.0",
31
+ "postcss-cssnext": "^3.0.2",
32
+ "postcss-loader": "^2.0.6",
33
+ "postcss-smart-import": "^0.7.5",
34
+ "rails-erb-loader": "^5.2.1",
35
+ "resolve-url-loader": "^2.1.0",
36
+ "sass-loader": "^6.0.6",
37
+ "style-loader": "^0.18.2",
38
+ "webpack": "^3.5.5",
39
+ "webpack-manifest-plugin": "^1.3.1"
40
+ },
41
+ "devDependencies": {
42
+ "eslint": "^3.16.1",
43
+ "eslint-config-airbnb": "^14.1.0",
44
+ "eslint-plugin-import": "^2.2.0",
45
+ "eslint-plugin-jsx-a11y": "^4.0.0",
46
+ "eslint-plugin-react": "^6.10.0"
47
+ },
48
+ "scripts": {
49
+ "test": "echo \"Error: no test specified\" && exit 1",
50
+ "lint": "eslint {package,lib}/"
51
+ },
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "git+https://github.com/webpacker-for-component.git"
55
+ },
56
+ "author": "Thomas Gauthey",
57
+ "license": "MIT",
58
+ "bugs": {
59
+ "url": "https://github.com/webpacker-for-component.git"
60
+ },
61
+ "homepage": "https://rubygems.org/gems/webpacker-for-component"
62
+ }
@@ -0,0 +1,21 @@
1
+ const config = require('./config')
2
+ const { resolve } = require('path')
3
+
4
+ function removeOuterSlashes(string) {
5
+ return string.replace(/^\/*/, '').replace(/\/*$/, '')
6
+ }
7
+
8
+ function formatPublicPath(host = '', path = '') {
9
+ let formattedHost = removeOuterSlashes(host)
10
+ if (formattedHost && !/^http/i.test(formattedHost)) {
11
+ formattedHost = `//${formattedHost}`
12
+ }
13
+ const formattedPath = removeOuterSlashes(path)
14
+ return `${formattedHost}/${formattedPath}/`
15
+ }
16
+
17
+ module.exports = {
18
+ path: resolve('public', config.public_output_path),
19
+ publicPath: `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1'),
20
+ publicPathWithHost: formatPublicPath(process.env.ASSET_HOST, config.public_output_path)
21
+ }
data/package/config.js ADDED
@@ -0,0 +1,8 @@
1
+ const { resolve } = require('path')
2
+ const { safeLoad } = require('js-yaml')
3
+ const { readFileSync } = require('fs')
4
+
5
+ const filePath = resolve('config', 'webpacker.yml')
6
+ const config = safeLoad(readFileSync(filePath), 'utf8')
7
+
8
+ module.exports = config[process.env.NODE_ENV]
@@ -0,0 +1,95 @@
1
+ /* eslint global-require: 0 */
2
+ /* eslint import/no-dynamic-require: 0 */
3
+
4
+ const config = require('./config')
5
+ const assetHost = require('./asset_host')
6
+
7
+ const { basename, dirname, join, relative, resolve } = require('path')
8
+ const { sync } = require('glob')
9
+ const extname = require('path-complete-extname')
10
+
11
+ const webpack = require('webpack')
12
+ const ExtractTextPlugin = require('extract-text-webpack-plugin')
13
+ const ManifestPlugin = require('webpack-manifest-plugin')
14
+
15
+ function getLoaderMap() {
16
+ const result = new Map()
17
+ const paths = sync(resolve(__dirname, 'loaders', '*.js'))
18
+ paths.forEach((path) => {
19
+ const name = basename(path, extname(path))
20
+ result.set(name, require(path))
21
+ })
22
+ return result
23
+ }
24
+
25
+ function getPluginMap() {
26
+ const result = new Map()
27
+ result.set('Environment', new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(process.env))))
28
+ result.set('ExtractText', new ExtractTextPlugin('[name]-[contenthash].css'))
29
+ result.set('Manifest', new ManifestPlugin({ publicPath: assetHost.publicPath, writeToFileEmit: true }))
30
+ return result
31
+ }
32
+
33
+ function getExtensionsGlob() {
34
+ const { extensions } = config
35
+ if (!extensions.length) {
36
+ throw new Error('You must configure at least one extension to compile in webpacker.yml')
37
+ }
38
+ return extensions.length === 1 ? `**/${extensions[0]}` : `**/*{${extensions.join(',')}}`
39
+ }
40
+
41
+ function getEntryObject() {
42
+ const result = {}
43
+ const glob = getExtensionsGlob()
44
+ const rootPath = join(config.source_path, config.source_entry_path)
45
+ const paths = sync(join(rootPath, glob))
46
+ paths.forEach((path) => {
47
+ const namespace = relative(join(rootPath), dirname(path))
48
+ const name = join(namespace, basename(path, extname(path)))
49
+ result[name] = resolve(path)
50
+ })
51
+ return result
52
+ }
53
+
54
+ function getModulePaths() {
55
+ let result = [resolve(config.source_path), 'node_modules']
56
+ if (config.resolved_paths) {
57
+ result = result.concat(config.resolved_paths)
58
+ }
59
+ return result
60
+ }
61
+
62
+ module.exports = class Environment {
63
+ constructor() {
64
+ this.loaders = getLoaderMap()
65
+ this.plugins = getPluginMap()
66
+ }
67
+
68
+ toWebpackConfig() {
69
+ return {
70
+ entry: getEntryObject(),
71
+
72
+ output: {
73
+ filename: '[name]-[chunkhash].js',
74
+ chunkFilename: '[name]-[chunkhash].chunk.js',
75
+ path: assetHost.path,
76
+ publicPath: assetHost.publicPath
77
+ },
78
+
79
+ module: {
80
+ rules: Array.from(this.loaders.values())
81
+ },
82
+
83
+ plugins: Array.from(this.plugins.values()),
84
+
85
+ resolve: {
86
+ extensions: config.extensions,
87
+ modules: getModulePaths()
88
+ },
89
+
90
+ resolveLoader: {
91
+ modules: ['node_modules']
92
+ }
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,46 @@
1
+ const Environment = require('../environment')
2
+ const { dev_server } = require('../config')
3
+ const assetHost = require('../asset_host')
4
+ const webpack = require('webpack')
5
+
6
+ module.exports = class extends Environment {
7
+ constructor() {
8
+ super()
9
+
10
+ if (dev_server.hmr) {
11
+ this.plugins.set('HotModuleReplacement', new webpack.HotModuleReplacementPlugin())
12
+ this.plugins.set('NamedModules', new webpack.NamedModulesPlugin())
13
+ }
14
+ }
15
+
16
+ toWebpackConfig() {
17
+ const result = super.toWebpackConfig()
18
+ if (dev_server.hmr) {
19
+ result.output.filename = '[name]-[hash].js'
20
+ }
21
+ result.output.pathinfo = true
22
+ result.devtool = 'cheap-eval-source-map'
23
+ result.devServer = {
24
+ host: dev_server.host,
25
+ port: dev_server.port,
26
+ https: dev_server.https,
27
+ hot: dev_server.hmr,
28
+ contentBase: assetHost.path,
29
+ publicPath: assetHost.publicPath,
30
+ clientLogLevel: 'none',
31
+ compress: true,
32
+ historyApiFallback: true,
33
+ headers: {
34
+ 'Access-Control-Allow-Origin': '*'
35
+ },
36
+ overlay: true,
37
+ watchOptions: {
38
+ ignored: /node_modules/
39
+ },
40
+ stats: {
41
+ errorDetails: true
42
+ }
43
+ }
44
+ return result
45
+ }
46
+ }
@@ -0,0 +1,34 @@
1
+ const Environment = require('../environment')
2
+ const webpack = require('webpack')
3
+ const CompressionPlugin = require('compression-webpack-plugin')
4
+
5
+ module.exports = class extends Environment {
6
+ constructor() {
7
+ super()
8
+
9
+ this.plugins.set('ModuleConcatenation', new webpack.optimize.ModuleConcatenationPlugin())
10
+
11
+ this.plugins.set('UglifyJs', new webpack.optimize.UglifyJsPlugin({
12
+ sourceMap: true,
13
+ compress: {
14
+ warnings: false
15
+ },
16
+ output: {
17
+ comments: false
18
+ }
19
+ }))
20
+
21
+ this.plugins.set('Compression', new CompressionPlugin({
22
+ asset: '[path].gz[query]',
23
+ algorithm: 'gzip',
24
+ test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/
25
+ }))
26
+ }
27
+
28
+ toWebpackConfig() {
29
+ const result = super.toWebpackConfig()
30
+ result.devtool = 'source-map'
31
+ result.stats = 'normal'
32
+ return result
33
+ }
34
+ }
@@ -0,0 +1,3 @@
1
+ const Environment = require('../environment')
2
+
3
+ module.exports = class extends Environment {}
data/package/index.js ADDED
@@ -0,0 +1,16 @@
1
+ /* eslint global-require: 0 */
2
+ /* eslint import/no-dynamic-require: 0 */
3
+
4
+ const Environment = require('./environment')
5
+ const { resolve } = require('path')
6
+ const { existsSync } = require('fs')
7
+
8
+ function createEnvironment() {
9
+ const path = resolve(__dirname, 'environments', `${process.env.NODE_ENV}.js`)
10
+ const constructor = existsSync(path) ? require(path) : Environment
11
+ return new constructor()
12
+ }
13
+
14
+ const environment = createEnvironment()
15
+
16
+ module.exports = { environment, Environment }
@@ -0,0 +1,11 @@
1
+ const { join } = require('path')
2
+ const { cache_path } = require('../config')
3
+
4
+ module.exports = {
5
+ test: /\.(js|jsx)?(\.erb)?$/,
6
+ exclude: /node_modules/,
7
+ loader: 'babel-loader',
8
+ options: {
9
+ cacheDirectory: join(cache_path, 'babel-loader')
10
+ }
11
+ }
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ test: /\.coffee(\.erb)?$/,
3
+ loader: 'coffee-loader'
4
+ }
@@ -0,0 +1,19 @@
1
+ const { resolve } = require('path')
2
+
3
+ const elmSource = resolve(process.cwd())
4
+ const elmMake = `${elmSource}/node_modules/.bin/elm-make`
5
+ const elmDefaultOptions = `cwd=${elmSource}&pathToMake=${elmMake}`
6
+
7
+ const loaderOptions = () => {
8
+ if (process.env.NODE_ENV === 'production') {
9
+ return `elm-webpack-loader?${elmDefaultOptions}`
10
+ }
11
+
12
+ return `elm-hot-loader!elm-webpack-loader?${elmDefaultOptions}&verbose=true&warn=true&debug=true`
13
+ }
14
+
15
+ module.exports = {
16
+ test: /\.elm(\.erb)?$/,
17
+ exclude: [/elm-stuff/, /node_modules/],
18
+ loader: loaderOptions()
19
+ }
@@ -0,0 +1,9 @@
1
+ module.exports = {
2
+ test: /\.erb$/,
3
+ enforce: 'pre',
4
+ exclude: /node_modules/,
5
+ loader: 'rails-erb-loader',
6
+ options: {
7
+ runner: 'bin/rails runner'
8
+ }
9
+ }
@@ -0,0 +1,15 @@
1
+ const config = require('../config')
2
+ const assetHost = require('../asset_host')
3
+ const { join } = require('path')
4
+
5
+ module.exports = {
6
+ test: /\.(jpg|jpeg|png|gif|svg|eot|ttf|woff|woff2)$/i,
7
+ use: [{
8
+ loader: 'file-loader',
9
+ options: {
10
+ name: '[path][name]-[hash].[ext]',
11
+ context: join(config.source_path),
12
+ publicPath: assetHost.publicPathWithHost
13
+ }
14
+ }]
15
+ }
@@ -0,0 +1,31 @@
1
+ const ExtractTextPlugin = require('extract-text-webpack-plugin')
2
+ const path = require('path')
3
+ const config = require('../config')
4
+
5
+ const postcssConfigPath = path.resolve(process.cwd(), '.postcssrc.yml')
6
+ const isProduction = process.env.NODE_ENV === 'production'
7
+ const extractCSS = !(config.dev_server && config.dev_server.hmr)
8
+
9
+ const extractOptions = {
10
+ fallback: 'style-loader',
11
+ use: [
12
+ { loader: 'css-loader', options: { minimize: isProduction } },
13
+ { loader: 'postcss-loader', options: { sourceMap: true, config: { path: postcssConfigPath } } },
14
+ 'resolve-url-loader',
15
+ { loader: 'sass-loader', options: { sourceMap: true } }
16
+ ]
17
+ }
18
+
19
+ // For production extract styles to a separate bundle
20
+ const extractCSSLoader = {
21
+ test: /\.(scss|sass|css)$/i,
22
+ use: ExtractTextPlugin.extract(extractOptions)
23
+ }
24
+
25
+ // For hot-reloading use regular loaders
26
+ const inlineCSSLoader = {
27
+ test: /\.(scss|sass|css)$/i,
28
+ use: ['style-loader'].concat(extractOptions.use)
29
+ }
30
+
31
+ module.exports = isProduction || extractCSS ? extractCSSLoader : inlineCSSLoader