When developing at least some large javascript project, you immediately understand that you cannot write all the code in a single file. After that, the code is spread across several files and directories and a simple script is written so that all these files can be easily merged into one large production file. After some time, you begin to notice that the farther you go, the harder it becomes to keep track of the dependencies between files, and the whole mechanism developed looks more like a crutch. And here comes the insight that it would be nice to see what are the solutions to this problem.# Assetfile # input "app/assets/javascripts" # output "public/javascripts" # , # input. #*.js, "app/assets/javascripts" match "*.js" do #ConcatFilter - , . # *.js app/assets/javascripts # application.js, #public/javascripts. filter Rake::Pipeline::ConcatFilter, "application.js" end # main.coffee ( ): require("file1") require("file2") require("file3") # file1.coffee ( ): # ... ... file1 = true # # file2.coffee ( 1- 3-): require("file1") require("file3") # ... ... file2 = true # # file3.coffee ( 1-): require("file1") # ... ... file3 = true # ! , , file1. , . # Gemfile source "http://rubygems.org" gem "rake-pipeline", :git => "https://github.com/livingsocial/rake-pipeline.git" gem "rake-pipeline-web-filters", :git => "https://github.com/wycats/rake-pipeline-web-filters.git" gem "uglifier", :git => "https://github.com/lautis/uglifier.git" group :development do gem "rack" gem "github_downloads" gem "coffee-script" end # Rakefile abort "Please use Ruby 1.9 to build application!" if RUBY_VERSION !~ /^1\.9/ require "bundler/setup" def pipeline require 'rake-pipeline' Rake::Pipeline::Project.new("Assetfile") end task :dist do puts "build application" pipeline.invoke puts "done" end task :default => :dist # Assetfile output "target" # Assetfile # "src" input "src" do # *.coffee ( "src") match "**/*.coffee" do require "rake-pipeline-web-filters" # javascript filter Rake::Pipeline::Web::Filters::CoffeeScriptFilter do |filename| # , ( ) # js . # "src" "target" # '.coffee' '.js' File.join("src/", filename.gsub('.coffee', '.js')) end end end # Assetfile # , name="application" # "target/src" input "target/src" do # main.js match "main.js" do # NeuterFilter. # , # . neuter( # , . :additional_dependencies => proc { |input| # , main Dir.glob(File.join(File.dirname(input.fullpath),'**','*.js')) }, # :path_transform => proc { |path, input| # require("file1") # . . # require("file1") require("file1.js") "#{path}.js" }, # , js- :closure_wrap => false ) do |filename| "#{name}.js" end end end # application.js (function() { var file1; file1 = true; }).call(this); (function() { var file3; file3 = true; }).call(this); (function() { require("file2"); }).call(this); require("file2"); # neuter_filter.rb regexp = @config[:require_regexp] || %r{^\s*require\(['"]([^'"]*)['"]\);?\s*} %r{^\s*require\(['"]([^'"]*)['"]\);?\s*} # Assetfile input "target/src" do match "main.js" do neuter( .... :closure_wrap => false, :require_regexp => %r{^\s*require\(['"]([^'"]*)['"]\);?\s*$} ... # application.js (function() { var file1; file1 = true; }).call(this); (function() { var file3; file3 = true; }).call(this); (function() { var file2; file2 = true; }).call(this); (function() { }).call(this); # Assetfile class ClosureFilter < Rake::Pipeline::Filter def generate_output(inputs, output) inputs.each do |input| # output.write "(function() {\n#{input.read}\n})()" end end end # Assetfile input "target/src" do match "main.js" do neuter( ............. ) do |filename| "#{name}.js" end filter ClosureFilter end end # Assetfile input "target" do match "#{name}.js" do # uglify - uglify{ "#{name}.min.js" } end end (function(){(function(){var e;e=!0}).call(this),function(){var e;e=!0}.call(this),function(){var e;e=!0}.call(this),function(){}.call(this)})(); # Assetfile require "json" require "rake-pipeline-web-filters" name="application" output "target" input "src" do match "**/*.coffee" do filter Rake::Pipeline::Web::Filters::CoffeeScriptFilter do |filename| File.join("src/", filename.gsub('.coffee', '.js')) end end end class ClosureFilter < Rake::Pipeline::Filter def generate_output(inputs, output) inputs.each do |input| output.write "(function() {\n#{input.read}\n})()" end end end input "target/src" do match "main.js" do neuter( :additional_dependencies => proc { |input| Dir.glob(File.join(File.dirname(input.fullpath),'**','*.js')) }, :path_transform => proc { |path, input| "#{path}.js" }, :closure_wrap => false, :require_regexp => %r{^\s*require\(['"]([^'"]*)['"]\);?\s*$} ) do |filename| "#{name}.js" end filter ClosureFilter end end input "target" do match "#{name}.js" do uglify{ "#{name}.min.js" } end end # vim: filetype=ruby require("dir_name/file_name") Source: https://habr.com/ru/post/148167/
All Articles