Permalink
Browse files

FIRST!1!

  • Loading branch information...
dhh committed Dec 7, 2016
0 parents commit f4cc31d445e54300d48e381b0381d87d31204588
@@ -0,0 +1,20 @@
Copyright (c) 2016 David Heinemeier Hansson, Basecamp
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,18 @@
# Webpacker
Webpacker makes it easy to use the JavaScript preprocessor and bundler Webpack
to manage application-like JavaScript in Rails. It coexists with the asset pipeline,
as the purpose is only to use Webpack for app-like JavaScript, not images, css, or
even JavaScript Sprinkles.
It's designed to work with Rails 5.1+ and makes use of the Yarn dependency management
that's been made default from that version forward. You can either make use of Webpacker
during setup of a new application with --webpack or you can uncomment the gem and run
`bin/rails webpacker:install` in an existing application.
When Webpacker has been installed...
FIXME: Write the rest...
## License
Webpacker is released under the [MIT License](http://www.opensource.org/licenses/MIT).
@@ -0,0 +1,7 @@
<%= shebang %>
BIN_PATH = File.expand_path('.', __dir__)
Dir.chdir(BIN_PATH) do
exec "./webpack --watch --progress --color #{ARGV.join(" ")}"
end
@@ -0,0 +1,15 @@
<%= shebang %>
RAILS_ENV = ENV['RAILS_ENV'] || 'development'
WEBPACK_ENV = ENV['WEBPACK_ENV'] || RAILS_ENV
APP_PATH = File.expand_path('../', __dir__)
VENDOR_PATH = File.expand_path('../vendor', __dir__)
SET_NODE_PATH = "NODE_PATH=#{VENDOR_PATH}/node_modules"
WEBPACK_BIN = "./node_modules/webpack/bin/webpack.js"
WEBPACK_CONFIG = "#{APP_PATH}/config/webpack/#{WEBPACK_ENV}.js"
Dir.chdir(VENDOR_PATH) do
exec "#{SET_NODE_PATH} #{WEBPACK_BIN} --config #{WEBPACK_CONFIG} #{ARGV.join(" ")}"
end
@@ -0,0 +1,14 @@
// Note: You must restart bin/webpack-watcher for changes to take effect
var path = require('path')
var webpack = require('webpack')
var _ = require('lodash')
var config = module.exports = require('./shared.js')
config = _.merge(config, {
debug: true,
displayErrorDetails: true,
outputPathinfo: true,
devtool: 'sourcemap',
})
@@ -0,0 +1,14 @@
// Note: You must restart bin/webpack-watcher for changes to take effect
var path = require('path')
var webpack = require('webpack')
var _ = require('lodash')
var config = module.exports = require('./shared.js');
config.output = _.merge(config.output, { filename: '[name]-[hash].js' })

This comment has been minimized.

Show comment
Hide comment
@guilleiguaran

guilleiguaran Dec 7, 2016

Member

@dhh I'm using webpack-merge that was created specifically for those cases, I'll send a PR for this in a moment so we can check what approach seems better.

@guilleiguaran

guilleiguaran Dec 7, 2016

Member

@dhh I'm using webpack-merge that was created specifically for those cases, I'll send a PR for this in a moment so we can check what approach seems better.

This comment has been minimized.

Show comment
Hide comment
@dhh

dhh Dec 7, 2016

Member
@dhh

dhh via email Dec 7, 2016

Member
config.plugins.push(
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.OccurenceOrderPlugin()
)
@@ -0,0 +1,31 @@
// Note: You must restart bin/webpack-watcher for changes to take effect
var path = require('path')
var glob = require('glob')
var _ = require('lodash')
module.exports = {
entry: _.keyBy(glob.sync('../app/javascript/packs/*.js'), function(entry) { return path.basename(entry, '.js') }),
output: { filename: '[name].js', path: '../public/packs' },
module: {
loaders: [
{ test: /\.coffee$/, loader: "coffee-loader" }
]
},
plugins: [],
resolve: {
extensions: [ '', '.js', '.coffee' ],
root: [
path.resolve('../app/javascript'),
path.resolve('../vendor/node_modules')
]
},
resolveLoader: {
modulesDirectories: [ path.resolve('../vendor/node_modules') ]
}
}
@@ -0,0 +1 @@
// var React = require('react')
@@ -0,0 +1,15 @@
INSTALL_PATH = File.dirname(__FILE__)
directory "#{INSTALL_PATH}/javascript", 'app/javascript'
directory "#{INSTALL_PATH}/bin", 'bin'
chmod 'bin', 0755 & ~File.umask, verbose: false
directory "#{INSTALL_PATH}/config", 'config/webpack'
run './bin/yarn add webpack lodash'
environment \
"# Make javascript_pack_tag lookup digest hash to enable long-term caching\n" +
" config.x.webpacker[:digesting] = true\n",
env: 'production'
@@ -0,0 +1,22 @@
PACKS_PATH = Rails.root.join('public/packs')
PACK_DIGESTS_PATH = PACKS_PATH.join('digests.json')
WEBPACKER_APP_TEMPLATE_PATH = File.expand_path('../install/template.rb', File.dirname(__FILE__))
namespace :webpacker do
desc "compile javascript packs using webpack for production with digests"
task :compile do
webpack_digests_json = JSON.parse(`WEBPACK_ENV=production ./bin/webpack --json`)['assetsByChunkName'].to_json
FileUtils.mkdir_p(PACKS_PATH)
File.open(PACK_DIGESTS_PATH, 'w+') { |file| file.write webpack_digests_json }
puts "Compiled digests for all packs in #{PACK_DIGESTS_PATH}: "
puts webpack_digests_json
end
desc "install webpacker in this application"
task :install do
exec "./bin/rails app:template LOCATION=#{WEBPACKER_APP_TEMPLATE_PATH}"
end
end
@@ -0,0 +1,4 @@
module Webpacker
end
require 'webpacker/railtie' if defined?(Rails)
@@ -0,0 +1,36 @@
class Webpacker::Digests
class_attribute :instance
class << self
def load(path)
self.instance = new(path)
end
def lookup(name)
if instance
instance.lookup(name)
else
raise "Webpacker::Digests.load(path) must be called first"
end
end
end
def initialize(path)
@path = path
load
end
def lookup(name)
@digests[name.to_s]
end
private
def load
begin
@digests = JSON.parse(File.read(@path))
rescue Errno::ENOENT
Rails.logger.error \
"Missing digests file at #{@path}! You must first compile the packs via rails webpacker:compile"
end
end
end
@@ -0,0 +1,7 @@
require 'webpacker/source'
module Webpacker::Helper
def javascript_pack_tag(name, **options)
tag.script src: Webpacker::Source.new(name).path, **options
end
end
@@ -0,0 +1,18 @@
require 'rails/railtie'
require 'webpacker/helper'
require 'webpacker/digests'
class Webpacker::Engine < ::Rails::Engine
initializer :webpacker do
ActiveSupport.on_load :action_controller do
ActionController::Base.helper Webpacker::Helper
end
if Rails.configuration.x.webpacker[:digesting]
Webpacker::Digests.load \
Rails.application.config.x.webpacker[:digests_path] ||
Rails.root.join('public/packs/digests.json')
end
end
end
@@ -0,0 +1,28 @@
class Webpacker::Source
def initialize(name)
@name = name
end
def path
if digesting?
"/packs/#{digested_filename}"
else
"/packs/#{filename}"
end
end
private
attr_accessor :name
def digesting?
Rails.configuration.x.webpacker[:digesting]
end
def digested_filename
Webpacker::Digests.lookup(name)
end
def filename
"#{name}.js"
end
end
@@ -0,0 +1,17 @@
Gem::Specification.new do |s|
s.name = 'webpacker'
s.version = '0.1'
s.authors = 'David Heinemeier Hansson'
s.email = 'david@basecamp.com'
s.summary = 'Use Webpack to manage app-like JavaScript modules in Rails'
s.homepage = 'https://github.com/rails/webpacker'
s.license = 'MIT'
s.required_ruby_version = '>= 1.9.3'
s.add_dependency 'activesupport', '>= 3.0.0', '< 5.1'
s.add_dependency 'multi_json', '~> 1.2'
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- test/*`.split("\n")
end

0 comments on commit f4cc31d

Please sign in to comment.