12

在创建静态应用程序时,我经常启动一个新的 Rails 应用程序。这使得一些事情变得更容易,比如编译(Coffeescript、SCSS)、最小化(JS、CSS)和浏览器限制(页面从 localhost:3000 提供,因此可以加载外部源等)。

最后,我想导出应用程序,以便将其放到网上。然后我只需要 HTML+CSS+JS。可以手动提取文件,但可能有一种更简单的方法。

那么:有没有一种工具可以存储来自 Rails 应用程序的已编译、最小化的 HTML+CSS+JS 文件?

4

8 回答 8

19

如果您只想复制网站,因为它将由 rails 呈现(并且不需要服务器端代码执行),您可以使用镜像 rails-website

wget --page-requisites --convert-links http://URL-to-Start

但是,这只会下载从条目 URL 引用的那些文件,因此您可能需要在所有子 URL 上单独运行它。

来源:下载网页的工作本地副本

于 2013-07-10T19:58:14.983 回答
5

同意 Screenmutt。我已经尝试了其中提到的几个,但在以下方面取得了最大的成功:

http://middlemanapp.com/

几乎可以满足您的所有要求,并让您导出为静态 HTML。

安装:

gem install middleman

创建项目:

middleman init my_new_project (or even better with template --template=html5)

在本地服务器上运行以进行实时编辑:

bundle exec middleman

转储静态代码:

bundle exec middleman build
于 2013-07-10T19:42:41.190 回答
3

也许您可以从提供它的本地主机“抓取”HTML?

一般而言,似乎有一些用于下载网站的工具......您可能可以将它们限制为localhost:3000仅下载资源。

于 2013-07-04T22:37:06.223 回答
1

更新:这是另一个可能有助于将 Rails 3.1 用于静态站点的教程

这不是常见的用法。您可以通过手动缓存所有内容来提取所有静态页面。

我建议看看一些替代方案

很抱歉,这不是一个好的答案,但老实说......您正在使用 Rails 做一些它从未打算做的事情。制作静态网站有很多更好的方法。

此外,静态网站不是“应用程序”。:)

于 2013-07-01T20:26:13.300 回答
1

您所要做的就是在本地切换到 Rails 生产模式,以便合并和缩小资产。然后您所要做的就是查看 HTML、CSS 和 JS 的源代码。这应该只需要几秒钟。

所以步骤是

  • config.assets.compress = true 在 development.rb
  • 在本地查看应用程序
  • 查看源代码,复制并粘贴到 index.html 文件中
  • 单击压缩的 CSS 和 JS 表单源并保存与 index.html 相关的内容,确保它们正确链接
于 2013-07-05T11:36:54.603 回答
1

您可以使用 Wget(如前所述)。我会去:

wget --mirror --convert-links --adjust-extension --page-requisites --no-parent http://www.yourdomain.com

哟也可以使用Httrack。

确保在设置 Httrack 时排除所有带有脚本的外部网站,这样您就不会下载 fe Google Analytics js 文件或 Adsense 或 Facebook 脚本。在 Httrack 中,您在首选项中排除它:

-*.googlesyndication.com/* -*.facebook.net/* -*.google-analytics.com/*

完成后,您仍然需要重写所有链接,因为它们将指向.../some-page/index.html您需要.../some-page/。这解决了从动态到静态脚本的问题。

于 2016-11-28T15:34:23.067 回答
0

您不应该从 rails 为它们提供服务,也不应该做任何将您的静态文件绑定到从 rails 提供服务的事情。您可能有一天会决定从 CDN 为您的应用程序提供服务。

JS

一个重要提示是查看使用 AMD(异步模块定义),它允许您指定 JS 文件依赖项。然后,您可以使用 require.js 和 r.js(在预编译步骤中抓取和编译依赖项的工具)。这对你的 JS 有用。

CSS

对于 CSS,您可以使用 sass 或更少。您最终会在页面上包含 1 个文件,但编译过程将涉及将您的 CSS 文件合并在一起。再一次,这可以在预编译步骤中完成。

内容分发网络

那里有一些宝石可以显示你的资产并将它们传递给像 S3 这样的东西,这个答案和其他类似的东西会有所帮助:有没有办法在推送到 heroku 时将管道资产资产到 s3?; 但是,当您第一次开始时,这不是必需的。

于 2013-07-10T22:48:49.843 回答
0

我使用一个 Rake 任务来完成它,该任务将一次获取每个 Rails 路由。它需要一些狡猾的扑克来处理您可能有冲突的路线这一事实 - 例如,wget 将/objects作为一个名为“objects”的文件获取,但是当您想要获取/objects/4它时,它会用一个名为“objects”的文件夹覆盖该文件嵌套文件名为“4”。所以我将每个下载的页面移动到同名目录中的“index.html”。

这是我的代码,我在其中lib/tasks/export.rake

def adjust_paths(path)
  text = File.read(path)
  new_contents = text.gsub(/("|\.\.\/)(assets|packs)\//, "\\1../\\2/")
  new_contents = new_contents.gsub("http://localhost:3020", "")
  File.write(path, new_contents)
end

namespace :static do
  desc 'Generate static site in ./out/ directory'
  task :export => [
      'assets:clean',
      'assets:precompile',
      :start_rails_server
  ] do

    begin
      out_prefix = "dist"

      paths = Rails.application.routes.routes.map do |route|
        route.path.spec.to_s
      end.uniq.reject { |p| p.starts_with?("/rails") || p == "/cable" || p == "/assets" }
      paths = paths.map { |p| p.sub("(.:format)", "") }

      paths.sort_by(&:length).each do |path|
        if path.include?(":id")
          # You'll have to use your own method for deciding which ids to use
          ids = ["1", "2", "3", "4"]
        else
          ids = [""]
        end
        ids.each do |id|
          id_path = path.sub(":id", id)
          `wget -P #{out_prefix} -nH -p -k http://localhost:3020#{id_path}`

          if id_path != "/"
            file_path = "#{out_prefix}#{id_path}"
            FileUtils.mv(file_path, "#{file_path}.tmp", force: true)
            FileUtils.mkdir_p(file_path)
            result = FileUtils.mv("#{file_path}.tmp", "#{file_path}/index.html", force: true)
            puts "Moving #{id_path} to #{id_path}/index.html: #{result}"

            # Will then need to relativise all of the asset paths, since we've moved it
            adjust_paths("#{file_path}/index.html")
          end

        end
      end

    ensure
      # stop the server when we're done
      Rake::Task['static:stop_rails_server'].reenable
      Rake::Task['static:stop_rails_server'].invoke
    end
  end

  desc 'Start a Rails server in the static Rails.env on port 3020'
  task :start_rails_server do
    `RAILS_SERVE_STATIC_FILES=1,RAILS_ENV=static rails s -p 3020 -d`
  end

  desc 'Stop Rails server'
  task :stop_rails_server do
    `cat tmp/pids/server.pid | xargs -I {} kill {}`
  end
end

然后你可以做bundle exec rake static:export

于 2020-09-30T13:09:28.203 回答