docker: avoid rebuilding CSS/JS assets on every commit.

Restructure the Dockerfile and the CSS/JS files so that we only rebuild
the CSS and JS when they change, not on every commit.

Before it took several minutes to rebuild the Docker image after every
commit, even when the JS/CSS files didn't change. This also made pulling
images slower.

This requires refactoring the CSS and JS to not use embedded Ruby (ERB)
templates, since this made the CSS and JS dependent on the Ruby
codebase, which is why we had to rebuild the assets after every Ruby
change.
This commit is contained in:
evazion
2021-10-12 23:03:08 -05:00
parent 587a9d0c8f
commit 206a4b5de5
17 changed files with 56 additions and 70 deletions

View File

@@ -1 +0,0 @@
.gitignore

View File

@@ -32,7 +32,7 @@ importAll(require.context('../src/styles', true, /\.s?css(?:\.erb)?$/));
importAll(require.context('../../components', true, /\.js(\.erb)?$/)); importAll(require.context('../../components', true, /\.js(\.erb)?$/));
importAll(require.context('../../components', true, /\.s?css(?:\.erb)?$/)); importAll(require.context('../../components', true, /\.s?css(?:\.erb)?$/));
import Autocomplete from "../src/javascripts/autocomplete.js.erb"; import Autocomplete from "../src/javascripts/autocomplete.js";
import Blacklist from "../src/javascripts/blacklists.js"; import Blacklist from "../src/javascripts/blacklists.js";
import CommentComponent from "../../components/comment_component/comment_component.js"; import CommentComponent from "../../components/comment_component/comment_component.js";
import CurrentUser from "../src/javascripts/current_user.js"; import CurrentUser from "../src/javascripts/current_user.js";
@@ -40,13 +40,13 @@ import Dtext from "../src/javascripts/dtext.js";
import IqdbQuery from "../src/javascripts/iqdb_queries.js"; import IqdbQuery from "../src/javascripts/iqdb_queries.js";
import Note from "../src/javascripts/notes.js"; import Note from "../src/javascripts/notes.js";
import PopupMenuComponent from "../../components/popup_menu_component/popup_menu_component.js"; import PopupMenuComponent from "../../components/popup_menu_component/popup_menu_component.js";
import Post from "../src/javascripts/posts.js.erb"; import Post from "../src/javascripts/posts.js";
import PostModeMenu from "../src/javascripts/post_mode_menu.js"; import PostModeMenu from "../src/javascripts/post_mode_menu.js";
import PostTooltip from "../src/javascripts/post_tooltips.js"; import PostTooltip from "../src/javascripts/post_tooltips.js";
import RelatedTag from "../src/javascripts/related_tag.js"; import RelatedTag from "../src/javascripts/related_tag.js";
import Shortcuts from "../src/javascripts/shortcuts.js"; import Shortcuts from "../src/javascripts/shortcuts.js";
import TagCounter from "../src/javascripts/tag_counter.js"; import TagCounter from "../src/javascripts/tag_counter.js";
import Upload from "../src/javascripts/uploads.js.erb"; import Upload from "../src/javascripts/uploads.js";
import UserTooltip from "../src/javascripts/user_tooltips.js"; import UserTooltip from "../src/javascripts/user_tooltips.js";
import Utility from "../src/javascripts/utility.js"; import Utility from "../src/javascripts/utility.js";
import Ugoira from "../src/javascripts/ugoira.js" import Ugoira from "../src/javascripts/ugoira.js"

View File

@@ -1,10 +1,5 @@
let Autocomplete = {}; let Autocomplete = {};
/* eslint-disable */
Autocomplete.TAG_CATEGORIES = <%= TagCategory.mapping.to_json.html_safe %>;
/* eslint-enable */
Autocomplete.TAG_PREFIXES = "-|~|" + Object.keys(Autocomplete.TAG_CATEGORIES).map(category => category + ":").join("|");
Autocomplete.MAX_RESULTS = 10; Autocomplete.MAX_RESULTS = 10;
Autocomplete.initialize_all = function() { Autocomplete.initialize_all = function() {
@@ -117,7 +112,7 @@ Autocomplete.insert_completion = function(input, completion) {
var before_caret_text = input.value.substring(0, input.selectionStart).replace(/^[ \t]+|[ \t]+$/gm, ""); var before_caret_text = input.value.substring(0, input.selectionStart).replace(/^[ \t]+|[ \t]+$/gm, "");
var after_caret_text = input.value.substring(input.selectionStart).replace(/^[ \t]+|[ \t]+$/gm, ""); var after_caret_text = input.value.substring(input.selectionStart).replace(/^[ \t]+|[ \t]+$/gm, "");
var regexp = new RegExp("(" + Autocomplete.TAG_PREFIXES + ")?\\S+$", "g"); var regexp = new RegExp("(" + Autocomplete.tag_prefixes().join("|") + ")?\\S+$", "g");
before_caret_text = before_caret_text.replace(regexp, "$1") + completion + " "; before_caret_text = before_caret_text.replace(regexp, "$1") + completion + " ";
input.value = before_caret_text + after_caret_text; input.value = before_caret_text + after_caret_text;
@@ -208,6 +203,10 @@ Autocomplete.autocomplete_source = function(query, type) {
}); });
} }
Autocomplete.tag_prefixes = function() {
return JSON.parse($("meta[name=autocomplete-tag-prefixes]").attr("content"));
};
$(document).ready(function() { $(document).ready(function() {
Autocomplete.initialize_all(); Autocomplete.initialize_all();
}); });

View File

@@ -1,4 +1,4 @@
import Post from './posts.js.erb' import Post from './posts.js'
import Utility from './utility' import Utility from './utility'
let PostModeMenu = {}; let PostModeMenu = {};

View File

@@ -3,8 +3,6 @@ import SparkMD5 from 'spark-md5';
let Upload = {}; let Upload = {};
Upload.MAX_FILE_SIZE_BYTES = <%= Danbooru.config.max_file_size.to_json %>;
Upload.MAX_FILE_SIZE = Upload.MAX_FILE_SIZE_BYTES / (1024 * 1024);
Upload.IQDB_LIMIT = 5; Upload.IQDB_LIMIT = 5;
Upload.IQDB_MIN_SIMILARITY = 50; Upload.IQDB_MIN_SIMILARITY = 50;
Upload.IQDB_HIGH_SIMILARITY = 70; Upload.IQDB_HIGH_SIMILARITY = 70;
@@ -183,8 +181,8 @@ Upload.initialize_dropzone = function() {
thumbnailMethod: "contain", thumbnailMethod: "contain",
addRemoveLinks: false, addRemoveLinks: false,
maxFiles: 1, maxFiles: 1,
maxFilesize: Upload.MAX_FILE_SIZE, maxFilesize: Upload.max_file_size(),
maxThumbnailFilesize: Upload.MAX_FILE_SIZE, maxThumbnailFilesize: Upload.max_file_size(),
timeout: 0, timeout: 0,
acceptedFiles: "image/jpeg,image/png,image/gif,video/mp4,video/webm", acceptedFiles: "image/jpeg,image/png,image/gif,video/mp4,video/webm",
previewTemplate: $("#dropzone-preview-template").html(), previewTemplate: $("#dropzone-preview-template").html(),
@@ -226,6 +224,10 @@ Upload.batch_open_all = function() {
$(".upload-preview > a").each((_i, link) => window.open(link.href)); $(".upload-preview > a").each((_i, link) => window.open(link.href));
}; };
Upload.max_file_size = function() {
return Number($("meta[name=max-file-size]").attr("content")) / (1024 * 1024);
};
$(function() { $(function() {
Upload.initialize_all(); Upload.initialize_all();
}); });

View File

@@ -23,11 +23,5 @@ div#c-modqueue {
margin-top: 1em; margin-top: 1em;
} }
} }
<% Danbooru.config.modqueue_warning_tags.each do |tag| %>
a[data-tag-name="<%= tag %>"] {
background-color: var(--modqueue-tag-warning-color);
}
<% end %>
} }
} }

View File

@@ -148,12 +148,11 @@
border: 1px solid var(--movable-note-box-border-color); border: 1px solid var(--movable-note-box-border-color);
} }
<% for i in 1..5 do %> &:not(:hover).level-1 { z-index: 101; }
<%# Selector order is deliberate as placing the not after the level consistently caused segmentaion faults for unknown reasons. %> &:not(:hover).level-2 { z-index: 102; }
&:not(:hover).level-<%= i %> { &:not(:hover).level-3 { z-index: 103; }
z-index: <%= 100 + i %>; &:not(:hover).level-4 { z-index: 104; }
} &:not(:hover).level-5 { z-index: 105; }
<% end %>
&:not(:hover) div.ui-resizable-handle { &:not(:hover) div.ui-resizable-handle {
display: none !important; display: none !important;

View File

@@ -23,6 +23,8 @@ class AutocompleteService
order: PostQueryBuilder::ORDER_METATAGS order: PostQueryBuilder::ORDER_METATAGS
} }
TAG_PREFIXES = ["-", "~"] + TagCategory.mapping.keys.map { |prefix| prefix + ":" }
attr_reader :query, :type, :limit, :current_user attr_reader :query, :type, :limit, :current_user
# Perform completion for the given search type and query. # Perform completion for the given search type and query.

View File

@@ -18,6 +18,8 @@
<meta name="blacklisted-tags" content="<%= CurrentUser.user.blacklisted_tags.gsub(/(?:\r|\n)+/, ",") %>"> <meta name="blacklisted-tags" content="<%= CurrentUser.user.blacklisted_tags.gsub(/(?:\r|\n)+/, ",") %>">
<% end %> <% end %>
<%= tag.meta name: "autocomplete-tag-prefixes", content: AutocompleteService::TAG_PREFIXES.to_json %>
<%# XXX hack to only load Ruffle on Flash posts %> <%# XXX hack to only load Ruffle on Flash posts %>
<% if controller_name == "posts" && action_name == "show" && @post&.is_flash? %> <% if controller_name == "posts" && action_name == "show" && @post&.is_flash? %>
<%= javascript_pack_tag "application", "flash" %> <%= javascript_pack_tag "application", "flash" %>

View File

@@ -1,5 +1,15 @@
<% page_title "Moderation Queue" %> <% page_title "Moderation Queue" %>
<%= content_for :html_header do %>
<style>
<% Danbooru.config.modqueue_warning_tags.each do |tag| %>
div.post a[data-tag-name="<%= tag %>"] {
background-color: var(--modqueue-tag-warning-color);
}
<% end %>
</style>
<% end %>
<% content_for(:top_content) do %> <% content_for(:top_content) do %>
<h1>Moderation Queue</h1> <h1>Moderation Queue</h1>

View File

@@ -1,3 +1,7 @@
<%= content_for :html_header do %>
<meta name="max-file-size" content="<%= Danbooru.config.max_file_size %>">
<% end %>
<div id="c-uploads"> <div id="c-uploads">
<div id="a-new" data-image-size="small"> <div id="a-new" data-image-size="small">
<h1>Upload</h1> <h1>Upload</h1>

View File

@@ -35,32 +35,37 @@ RUN \
rm -rf "$(gem environment gemdir)/cache" && \ rm -rf "$(gem environment gemdir)/cache" && \
find "$(gem environment gemdir)" -name "*.o" -delete find "$(gem environment gemdir)" -name "*.o" -delete
COPY .yarn package.json yarn.lock ./ COPY .yarnrc.yml package.json yarn.lock ./
COPY .yarn/ ./.yarn/
RUN yarn install RUN yarn install
COPY . . COPY postcss.config.js Rakefile ./
COPY bin/rails bin/webpack ./bin/
ARG SOURCE_COMMIT COPY config/application.rb config/boot.rb config/danbooru_default_config.rb config/webpacker.yml ./config/
RUN echo "$SOURCE_COMMIT" > REVISION COPY config/webpack/ ./config/webpack/
COPY public/images ./public/images
COPY public/fonts ./public/fonts
COPY app/components/ ./app/components/
FROM development AS assets COPY app/javascript/ ./app/javascript/
RUN \ RUN \
bin/rails assets:precompile && \ bin/rails assets:precompile && \
rm -rf \ rm -rf \
node_modules .yarn/cache tmp /usr/local/share/.cache/yarn \ node_modules .yarn/cache tmp /usr/local/share/.cache/yarn \
/root/.yarn/berry/cache /root/.bundle/cache /root/.npm && \ /root/.yarn/berry/cache /root/.bundle/cache /root/.npm && \
asdf uninstall nodejs && \ ln -s /tmp tmp && \
ln -s /tmp tmp ln -s packs public/packs-test
FROM base as production FROM base as production
COPY --from=development /root /root COPY --from=development /root /root
COPY --from=assets /danbooru /danbooru COPY --from=development /danbooru /danbooru
COPY . .
ARG SOURCE_COMMIT
RUN echo "$SOURCE_COMMIT" > REVISION
USER danbooru USER danbooru
ENTRYPOINT ["tini", "--"] ENTRYPOINT ["tini", "--"]

View File

@@ -13,15 +13,6 @@ module.exports = merge(webpackConfig, {
}, },
module: { module: {
rules: [{ rules: [{
// https://github.com/usabilityhub/rails-erb-loader
test: /.erb$/,
enforce: "pre",
exclude: /node_modules/,
loader: "rails-erb-loader",
options: {
runner: "bin/rails runner"
}
}, {
test: /\.wasm$/, test: /\.wasm$/,
type: 'asset/resource', type: 'asset/resource',
generator: { generator: {

View File

@@ -26,7 +26,6 @@
"postcss-import": "^14.0.2", "postcss-import": "^14.0.2",
"postcss-loader": "^6.1.1", "postcss-loader": "^6.1.1",
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",
"rails-erb-loader": "^5.5.2",
"ruffle-mirror": "2021.10.12", "ruffle-mirror": "2021.10.12",
"sass": "^1.38.2", "sass": "^1.38.2",
"sass-loader": "^12.1.0", "sass-loader": "^12.1.0",

View File

@@ -5864,7 +5864,7 @@ fsevents@~2.3.2:
languageName: node languageName: node
linkType: hard linkType: hard
"loader-utils@npm:^1.1.0, loader-utils@npm:^1.4.0": "loader-utils@npm:^1.4.0":
version: 1.4.0 version: 1.4.0
resolution: "loader-utils@npm:1.4.0" resolution: "loader-utils@npm:1.4.0"
dependencies: dependencies:
@@ -5917,13 +5917,6 @@ fsevents@~2.3.2:
languageName: node languageName: node
linkType: hard linkType: hard
"lodash.defaults@npm:^4.2.0":
version: 4.2.0
resolution: "lodash.defaults@npm:4.2.0"
checksum: fde72e71f7b7ece10c24e43dd601574168467d50bc76687302d40de341d5cb8e35b100105d938458747d2ad5f20d8bb736e62523ef39d1a8b40f7307c50f10ac
languageName: node
linkType: hard
"lodash.get@npm:^4.0": "lodash.get@npm:^4.0":
version: 4.4.2 version: 4.4.2
resolution: "lodash.get@npm:4.4.2" resolution: "lodash.get@npm:4.4.2"
@@ -7885,18 +7878,6 @@ fsevents@~2.3.2:
languageName: node languageName: node
linkType: hard linkType: hard
"rails-erb-loader@npm:^5.5.2":
version: 5.5.2
resolution: "rails-erb-loader@npm:5.5.2"
dependencies:
loader-utils: ^1.1.0
lodash.defaults: ^4.2.0
peerDependencies:
webpack: ^2.0.0 || >= 3.0.0-rc.0 || ^3.0.0
checksum: 3862a70a892db8392990f2a48431597c30ca88260dfa0a658bc612db944ec7138411aa9fbe5219fb9c08a66659073720b016d39580d58c5cd0ff810bbd5f31d0
languageName: node
linkType: hard
"randombytes@npm:^2.1.0": "randombytes@npm:^2.1.0":
version: 2.1.0 version: 2.1.0
resolution: "randombytes@npm:2.1.0" resolution: "randombytes@npm:2.1.0"
@@ -8387,7 +8368,6 @@ fsevents@~2.3.2:
postcss-import: ^14.0.2 postcss-import: ^14.0.2
postcss-loader: ^6.1.1 postcss-loader: ^6.1.1
postcss-preset-env: ^6.7.0 postcss-preset-env: ^6.7.0
rails-erb-loader: ^5.5.2
ruffle-mirror: 2021.10.12 ruffle-mirror: 2021.10.12
sass: ^1.38.2 sass: ^1.38.2
sass-loader: ^12.1.0 sass-loader: ^12.1.0