Replace Webpacker with Esbuild (#20470)

* Migrate to esbuild WIP

* Add exclude

* Remove redundant file

* Move file

* Move to javascript_include_tag

* Lint fix

* WIP

* WIP

* Add watch mode to esbuild WIP

* Get jest working

* Remove babel

* Revert "Remove babel"

This reverts commit 6da35260aa19d6f97f586deb66c0ecaf48433b73.

* More WIP

* Got image to load

* WIP

* Resolve audit

* Lint fix

* WIP

* Fix jest spec

* [CI] Remove asset-restore for test build stage

* Production compliant

* Temp disable sourcemap

* Update glob

* Add esbuild helper to stimulus

* Import fragment

* Temp disable coverage to see failing tests

* Fix broken spec

* Address lint

* Set proper es6 target

* Use esbuild for everything

* wait what

* Revert "Set proper es6 target"

This reverts commit 98f5278093421baa8ffe2ca580845b01c1a1eadf.

* Revert "Use esbuild for everything"

This reverts commit 0ac46738f07ffcb6af095ccb1ffa5e439b7fefa3.

* Replace uglifier with terser

* New compiled assets version

* Remvoe honeybadger-io/webpack

* Remove cypress coverage checks for now

* Update jsconfig.json

* Update docker-compose

* Remove public/packs-test from ci cache
This commit is contained in:
Mac Siri 2024-01-25 15:29:21 -05:00 committed by GitHub
parent 9e241ce456
commit afa73e06e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
105 changed files with 593 additions and 2497 deletions

View file

@ -73,10 +73,9 @@ jobs:
fail-on-cache-miss: false
path: |
public/assets
public/packs-test
tmp/cache/webpacker
key: ${{ runner.os }}-compiled-assets-v2-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }}
restore-keys: ${{ runner.os }}-compiled-assets-v2-
key: ${{ runner.os }}-compiled-assets-v3-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }}
restore-keys: ${{ runner.os }}-compiled-assets-v3-
- name: setup ruby
uses: ruby/setup-ruby@v1
with:
@ -163,10 +162,9 @@ jobs:
fail-on-cache-miss: true
path: |
public/assets
public/packs-test
tmp/cache/webpacker
key: ${{ runner.os }}-compiled-assets-v2-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }}
restore-keys: ${{ runner.os }}-compiled-assets-v2-
key: ${{ runner.os }}-compiled-assets-v3-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }}
restore-keys: ${{ runner.os }}-compiled-assets-v3-
- name: Restore node_modules
uses: actions/cache/restore@v3
with:
@ -288,16 +286,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Restore compiled assets
uses: actions/cache/restore@v3
with:
fail-on-cache-miss: true
path: |
public/assets
public/packs-test
tmp/cache/webpacker
key: ${{ runner.os }}-compiled-assets-v2-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }}
restore-keys: ${{ runner.os }}-compiled-assets-v2-
- name: Restore node_modules
uses: actions/cache/restore@v3
with:
@ -348,10 +336,9 @@ jobs:
fail-on-cache-miss: true
path: |
public/assets
public/packs-test
tmp/cache/webpacker
key: ${{ runner.os }}-compiled-assets-v2-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }}
restore-keys: ${{ runner.os }}-compiled-assets-v2-
key: ${{ runner.os }}-compiled-assets-v3-${{ hashFiles('app/assets/**', 'app/javascript/**', 'config/webpack/**', 'config/webpacker.yml', '**/package.json', '**/yarn.lock', '**/babel.config.js') }}
restore-keys: ${{ runner.os }}-compiled-assets-v3-
- name: Restore node_modules
uses: actions/cache/restore@v3
with:
@ -394,15 +381,6 @@ jobs:
path: |
tmp/cypress_screenshots
cypress/logs
- name: rename folder
run: |
rm -rf coverage/cypress/lcov-report
mv coverage/cypress coverage/cypress-${{ matrix.ci_node_index }}
- name: Upload test coverage result
uses: actions/upload-artifact@v3
with:
name: coverage
path: coverage/
- name: Upload test results to BuildPulse for flaky test detection
if: '!cancelled()' # Run this step even when the tests fail. Skip if the workflow is cancelled.
uses: Workshop64/buildpulse-action@master
@ -424,7 +402,6 @@ jobs:
- run: |
mkdir coverage coverage/simplecov coverage/cypress
mv simplecov-* coverage/simplecov
mv cypress-* coverage/cypress
mv jest coverage/jest
- uses: Wandalen/wretry.action@master
with:
@ -444,15 +421,6 @@ jobs:
fail_ci_if_error: ${{ github.ref != 'refs/heads/main' }}
attempt_limit: 5
attempt_delay: 60000
- uses: Wandalen/wretry.action@master
with:
action: codecov/codecov-action@v3
with: |
flags: cypress, javascript
directory: coverage/cypress
fail_ci_if_error: ${{ github.ref != 'refs/heads/main' }}
attempt_limit: 5
attempt_delay: 60000
CI-status-report:
runs-on: ubuntu-latest

3
.gitignore vendored
View file

@ -114,3 +114,6 @@ doc/
# spec reports
/spec/reports
/junit.xml
/app/assets/builds/*
!/app/assets/builds/.keep

View file

@ -55,6 +55,7 @@ gem "imgproxy", "~> 2.1" # A gem that easily generates imgproxy URLs for your im
gem "inline_svg", "~> 1.8" # Embed SVG documents in your Rails views and style them with CSS
gem "jbuilder", "~> 2.11" # Create JSON structures via a Builder-style DSL
gem "js-routes", "~> 2.2" # Brings Rails named routes to javascript
gem "jsbundling-rails", "~> 1.2" # A Rails plugin to bundle JavaScript
gem "jsonapi-serializer", "~> 2.2" # Serializer for Ruby objects
gem "kaminari", "~> 1.2" # A Scope & Engine based, clean, powerful, customizable and sophisticated paginator
gem "katex", "~> 0.9.0" # This rubygem enables you to render TeX math to HTML using KaTeX. It uses ExecJS under the hood
@ -106,13 +107,12 @@ gem "staccato", "~> 0.5" # Ruby Google Analytics Measurement
gem "sterile", "~> 1.0" # Transliterate Unicode and Latin1 text to 7-bit ASCII for URLs
gem "stripe", "~> 5.55" # Ruby library for the Stripe API
gem "strong_migrations", "~> 1.2" # Catch unsafe migrations
gem "terser", "~> 1.1" # Terser is a Ruby wrapper for the terser JavaScript parser and minifier
gem "twitter", "~> 7.0" # A Ruby interface to the Twitter API
gem "uglifier", "~> 4.2" # Uglifier minifies JavaScript files
gem "validate_url", "~> 1.0" # Library for validating urls in Rails
gem "vault", "~> 0.17" # Used to store secrets
gem "warning", "~> 1.3" # Adds custom processing for warnings, including the ability to ignore specific warning messages
gem "wcag_color_contrast", "~> 0.1" # Detect contrast of colors to determine readability and a11y.
gem "webpacker", "~> 5.4.3" # Use webpack to manage app-like JavaScript modules in Rails
group :development do
gem "better_errors", "~> 2.9" # Provides a better error page for Rails and other Rack apps

View file

@ -430,6 +430,8 @@ GEM
sass (>= 3.2)
js-routes (2.2.8)
railties (>= 4)
jsbundling-rails (1.2.1)
railties (>= 6.0.0)
json (2.7.1)
json-schema (2.8.1)
addressable (>= 2.4)
@ -633,8 +635,6 @@ GEM
rack
rack-protection (3.1.0)
rack (~> 2.2, >= 2.2.4)
rack-proxy (0.7.6)
rack
rack-test (2.1.0)
rack (>= 1.3)
rack-timeout (0.6.3)
@ -825,7 +825,6 @@ GEM
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
sax-machine (1.3.2)
semantic_range (3.0.0)
sexp_processor (4.16.1)
shellany (0.0.1)
shoulda-matchers (5.3.0)
@ -897,6 +896,8 @@ GEM
activerecord (>= 5.2)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
terser (1.1.20)
execjs (>= 0.3.0, < 3)
test-prof (1.3.1)
thor (1.3.0)
thread (0.2.2)
@ -917,8 +918,6 @@ GEM
simple_oauth (~> 0.3.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unaccent (0.4.0)
unf (0.1.4)
unf_ext
@ -945,11 +944,6 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (5.4.4)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
semantic_range (>= 2.3.0)
webpush (1.1.0)
hkdf (~> 0.2)
jwt (~> 2.0)
@ -1044,6 +1038,7 @@ DEPENDENCIES
inline_svg (~> 1.8)
jbuilder (~> 2.11)
js-routes (~> 2.2)
jsbundling-rails (~> 1.2)
jsonapi-serializer (~> 2.2)
kaminari (~> 1.2)
katex (~> 0.9.0)
@ -1118,10 +1113,10 @@ DEPENDENCIES
stripe (~> 5.55)
stripe-ruby-mock (= 3.1.0.rc3)
strong_migrations (~> 1.2)
terser (~> 1.1)
test-prof (~> 1.0)
timecop (~> 0.9)
twitter (~> 7.0)
uglifier (~> 4.2)
validate_url (~> 1.0)
vault (~> 0.17)
vcr (~> 6.1)
@ -1129,7 +1124,6 @@ DEPENDENCIES
wcag_color_contrast (~> 0.1)
web-console (~> 4.2)
webmock (~> 3.17)
webpacker (~> 5.4.3)
with_model (~> 2.1.7)
yard (~> 0.9)
yard-activerecord (~> 0.0)

View file

@ -1,3 +1,3 @@
web: bin/rails s -p 3000 -b 0.0.0.0
webpacker: ./bin/webpack-dev-server
sidekiq: bundle exec sidekiq
js: yarn build --watch

0
app/assets/builds/.keep Normal file
View file

View file

@ -5,3 +5,4 @@
//= link s3_direct_upload.js
//= link katex.css
//= link icon.png
//= link_tree ../builds

View file

@ -8,7 +8,7 @@ export default class SnackbarController extends Controller {
const [{ h, render }, { Snackbar }] = await Promise.all([
import('preact'),
// eslint-disable-next-line import/no-unresolved
import('Snackbar'),
import('../../Snackbar'),
]);
render(<Snackbar lifespan="3" />, this.snackZoneTarget);
@ -25,7 +25,7 @@ export default class SnackbarController extends Controller {
const { message, addCloseButton = false } = event.detail;
// eslint-disable-next-line import/no-unresolved
const { addSnackbarItem } = await import('Snackbar');
const { addSnackbarItem } = await import('../../Snackbar');
addSnackbarItem({ message, addCloseButton });
}
}

View file

@ -1,7 +1,7 @@
import { h } from 'preact';
import { useCallback } from 'preact/hooks';
import { ButtonNew as Button, Icon } from '@crayons';
import { Close } from '@images/x.svg';
import Close from '@images/x.svg';
/**
* Higher-order component that returns a template responsible for the layout of

View file

@ -1,7 +1,7 @@
import { h } from 'preact';
import PropTypes from 'prop-types';
import { ButtonNew as Button, Icon } from '@crayons';
import { Close } from '@images/x.svg';
import Close from '@images/x.svg';
/**
* Responsible for the layout of a tag autocomplete selected item in the article form

View file

@ -1,5 +1,5 @@
import { Application } from '@hotwired/stimulus';
import { definitionsFromContext } from '@hotwired/stimulus-webpack-helpers';
import { definitions } from 'stimulus:../admin/controllers'; // eslint-disable-line import/no-unresolved
import Rails from '@rails/ujs';
import 'focus-visible';
@ -11,5 +11,4 @@ Rails.start();
// section of the application.
const application = Application.start();
const context = require.context('admin/controllers', true, /.js$/);
application.load(definitionsFromContext(context));
application.load(definitions);

View file

@ -1,7 +1,7 @@
import { h } from 'preact';
import { Fragment, h } from 'preact';
import PropTypes from 'prop-types';
import { Icon, ButtonNew as Button } from '@crayons';
import { Close } from '@images/x.svg';
import Close from '@images/x.svg';
/**
* Responsible for the layout of a selected item in the crayons autocomplete and multi input components

View file

@ -1,9 +1,11 @@
const importModule = () => import('@utilities/codeFullscreenModeSwitcher');
import {
addFullScreenModeControl,
getFullScreenModeStatus,
onPressEscape,
onPopstate,
} from '@utilities/codeFullscreenModeSwitcher';
describe('CodeFullScreenModeSwitcher Utility', () => {
let addFullScreenModeControl, getFullScreenModeStatus;
let onPressEscape, onPopstate;
const getFullScreenElements = () =>
['.js-fullscreen-code.is-open', '.js-code-highlight.is-fullscreen'].map(
(selector) => document.body.querySelector(selector),
@ -40,19 +42,9 @@ describe('CodeFullScreenModeSwitcher Utility', () => {
</div>
<div class="js-fullscreen-code"></div>
`;
});
beforeAll(async () => {
({ addFullScreenModeControl, getFullScreenModeStatus } =
await importModule());
addFullScreenModeControl(getEnterFullScreenButtons());
});
beforeAll(async () => {
// eventListener functions
({ onPressEscape, onPopstate } = await importModule());
});
// Assertions are called within the `testNonFullScreen` function.
// eslint-disable-next-line jest/expect-expect
it('starts in non-fullscreen mode', testNonFullScreen);

View file

@ -1,7 +1,5 @@
let isFullScreenModeCodeOn = false;
let screenScroll = 0;
const fullScreenWindow =
document.getElementsByClassName('js-fullscreen-code')[0];
const { body } = document;
export function getFullScreenModeStatus() {
@ -67,6 +65,8 @@ function removeFullScreenModeControl(elements) {
}
function fullScreenModeControl(event) {
const fullScreenWindow =
document.getElementsByClassName('js-fullscreen-code')[0];
const codeBlock = event?.currentTarget.closest('.js-code-highlight')
? event.currentTarget.closest('.js-code-highlight').cloneNode(true)
: null;

View file

@ -52,4 +52,4 @@
</div>
<%= render partial: "image_upload_script" %>
<%= javascript_packs_with_chunks_tag "admin/convertUserIdsToUsernameInputs" %>
<%= javascript_include_tag "admin/convertUserIdsToUsernameInputs" %>

View file

@ -157,4 +157,4 @@
</div>
</div>
<%= javascript_packs_with_chunks_tag "admin/billboards", defer: true %>
<%= javascript_include_tag "admin/billboards", defer: true %>

View file

@ -82,4 +82,4 @@
</div>
</fieldset>
</div>
<%= javascript_packs_with_chunks_tag "admin/creatorOnboarding", defer: true %>
<%= javascript_include_tag "admin/creatorOnboarding", defer: true %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/users/gdprDeleteRequests", defer: true %>
<%= javascript_include_tag "admin/users/gdprDeleteRequests", defer: true %>
<div id="gdpr-delete-requests-content" class="crayons-card overflow-admin-main-layout-padding p-4 m:p-0">
<header class="flex flex-col l:flex-row justify-between l:items-center p-0 m:p-7 pb-4">
<h1 class="crayons-title ml-3 l:ml-0">GDPR Actions</h1>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/users/controls", "admin/users/memberIndex", defer: true %>
<%= javascript_include_tag "admin/users/controls", "admin/users/memberIndex", defer: true %>
<div id="member-index-content" class="crayons-card overflow-admin-main-layout-padding p-0">
<header class="flex flex-col p-4 xl:p-7 pb-4">
<div class="flex flex-col l:flex-row justify-between l:items-center">

View file

@ -29,4 +29,4 @@
<%= text_area_tag :social_preview_description, @listing_category.social_preview_description, size: "100x10", class: "crayons-textfield" %>
</div>
</div>
<%= javascript_packs_with_chunks_tag "enhanceColorPickers", defer: true %>
<%= javascript_include_tag "enhanceColorPickers", defer: true %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/organizations", defer: true %>
<%= javascript_include_tag "admin/organizations", defer: true %>
<header>
<section class="crayons-card flex flex-col l:flex-row gap-2 m:gap-4 l:gap-6 mb-2 m:mb-3 p-3 s:p-4 m:p-7">
<span class="crayons-logo crayons-logo--3xl">

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/overview", defer: true %>
<%= javascript_include_tag "admin/overview", defer: true %>
<h1 class="crayons-title mb-4">
Overview

View file

@ -47,7 +47,7 @@
autocomplete: "off",
data: { all_countries: billboard_all_countries_for_editing } %>
</div>
<%= javascript_packs_with_chunks_tag "admin/billboardEnabledCountries", defer: true %>
<%= javascript_include_tag "admin/billboardEnabledCountries", defer: true %>
<% end %>
</fieldset>
<%= render "update_setting_button", f: f %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/config/smtp", defer: true %>
<%= javascript_include_tag "admin/config/smtp", defer: true %>
<%= form_for(Settings::SMTP.new,
url: admin_settings_smtp_settings_path,

View file

@ -137,4 +137,4 @@
</details>
<% end %>
</div>
<%= javascript_packs_with_chunks_tag "enhanceColorPickers", defer: true %>
<%= javascript_include_tag "enhanceColorPickers", defer: true %>

View file

@ -27,4 +27,4 @@
<%= render partial: "forms/user_experience" %>
</div>
<%= javascript_packs_with_chunks_tag "admin/convertUserIdsToUsernameInputs" %>
<%= javascript_include_tag "admin/convertUserIdsToUsernameInputs" %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/shared/flagReactionItemDropdownButton", defer: true %>
<%= javascript_include_tag "admin/shared/flagReactionItemDropdownButton", defer: true %>
<% if vomit_reactions.present? %>
<% vomit_reactions.each do |vomit_reaction| %>
<%= render "admin/shared/flag_reaction_item", vomit_reaction: vomit_reaction, text_section: text_section %>

View file

@ -63,4 +63,4 @@
</div>
<%= f.submit class: "crayons-btn mt-3" %>
<% end %>
<%= javascript_packs_with_chunks_tag "enhanceColorPickers", defer: true %>
<%= javascript_include_tag "enhanceColorPickers", defer: true %>

View file

@ -48,4 +48,4 @@
</div>
</div>
<%= javascript_packs_with_chunks_tag "admin/convertUserIdsToUsernameInputs" %>
<%= javascript_include_tag "admin/convertUserIdsToUsernameInputs" %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/users/memberIndex", defer: true %>
<%= javascript_include_tag "admin/users/memberIndex", defer: true %>
<div id="member-index-content" class="crayons-card overflow-admin-main-layout-padding p-4 xl:p-0">
<header class="xl:p-7 pb-4 mx-2">
<div class="flex flex-col l:flex-row justify-between l:items-center">

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/users/controls", defer: true %>
<%= javascript_include_tag "admin/users/controls", defer: true %>
<%= form_with url: admin_users_path, method: :get, local: true do |f| %>
<div class="flex m:flex-col xl:flex-row justify-between m:items-end xl:justify-end xl:items-center mb-4">

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "admin/editUser", defer: true %>
<%= javascript_include_tag "admin/editUser", defer: true %>
<div class="flex relative justify-between s:justify-end gap-2 my-2 s:my-0">
<a id="tag-priority-link" href="<%= dashboard_show_user_path(username: @user.username ) %>" class="c-link c-link--block c-link--icon-alone" aria-label="<%= t("views.main.tags.aria_label") %>" title="<%= t("views.main.tags.aria_label") %>">
<%= crayons_icon_tag("dashboard-line") %>

View file

@ -13,4 +13,4 @@
</aside>
</div>
<%= javascript_packs_with_chunks_tag "billboard", defer: true %>
<%= javascript_include_tag "billboard", defer: true %>

View file

@ -29,5 +29,5 @@
<%= render "shared/webcomponents_loader_script" %>
<%= render "articles/v2_form", article: @article, organizations: @organizations, version: @version %>
<%= javascript_packs_with_chunks_tag "articleForm", defer: true %>
<%= javascript_include_tag "articleForm", defer: true %>
<div id="markdown-lint-js-path" class="hidden" data-markdown-it-js-path="<%= asset_path("markdown-it.min.js") %>" data-markdown-lint-js-path="<%= asset_path("markdownlint-browser.min.js") %>">

View file

@ -24,7 +24,7 @@
<%= auto_discovery_link_tag(:rss, app_url("feed"), title: t("views.stories.meta.rss", name: community_name)) %>
<% end %>
<%= javascript_packs_with_chunks_tag "homePage", defer: true %>
<%= javascript_include_tag "homePage", defer: true %>
<% cache(release_adjusted_cache_key("main-stories-index-#{params}-#{user_signed_in?}"), expires_in: 90.seconds) do %>
<% if @hero_billboard && FeatureFlag.enabled?(:hero_billboard) %>
<%= render partial: "shared/billboard", locals: { billboard: @hero_billboard, data_context_type: BillboardEvent::CONTEXT_TYPE_HOME } %>
@ -108,5 +108,5 @@
<%= render "articles/sidebar_additional" %>
</div>
<%= javascript_packs_with_chunks_tag "storiesList", "followButtons", "feedPreviewCards", "heroBannerClose", "localizeArticleDates", "feedEvents", defer: true %>
<%= javascript_include_tag "storiesList", "followButtons", "feedPreviewCards", "heroBannerClose", "localizeArticleDates", "feedEvents", defer: true %>
<% end %>

View file

@ -6,7 +6,7 @@
<% if user_signed_in? %>
<%= render "shared/webcomponents_loader_script" %>
<%= render "articles/v2_form", article: @article, organizations: @organizations, version: @version %>
<%= javascript_packs_with_chunks_tag "articleForm", defer: true %>
<%= javascript_include_tag "articleForm", defer: true %>
<div id="markdown-lint-js-path" class="hidden" data-markdown-it-js-path="<%= asset_path("markdown-it.min.js") %>" data-markdown-lint-js-path="<%= asset_path("markdownlint-browser.min.js") %>">
<% else %>
<% @new_article_not_logged_in = true %>

View file

@ -8,9 +8,9 @@
<%= render "shared/webcomponents_loader_script" %>
<% if user_signed_in? %>
<%= javascript_packs_with_chunks_tag "webShare", "articlePage", "articleModerationTools", "commentDropdowns", defer: true %>
<%= javascript_include_tag "webShare", "articlePage", "articleModerationTools", "commentDropdowns", defer: true %>
<% else %>
<%= javascript_packs_with_chunks_tag "webShare", "articlePage", "commentDropdowns", defer: true %>
<%= javascript_include_tag "webShare", "articlePage", "commentDropdowns", defer: true %>
<% end %>
<% cache("content-related-optional-scripts-#{@article.id}-#{@article.updated_at}-#{internal_navigation?}-#{user_signed_in?}", expires_in: 30.hours) do %>
@ -236,7 +236,7 @@
<%= render "moderations/modals/unflag_user_modal" %>
<div class="fullscreen-code js-fullscreen-code"></div>
<%= javascript_packs_with_chunks_tag "followButtons", "billboard", "localizeArticleDates", "articleReactions", defer: true %>
<%= javascript_include_tag "followButtons", "billboard", "localizeArticleDates", "articleReactions", defer: true %>
<script>
<%# we consider these scripts safe for embedding as they come from our code %>

View file

@ -7,4 +7,4 @@
<%= render "shared/stats" %>
</main>
<%= javascript_packs_with_chunks_tag "analyticsArticle", defer: true %>
<%= javascript_include_tag "analyticsArticle", defer: true %>

View file

@ -17,7 +17,7 @@
<% @articles.each do |article| %>
<%= render "articles/single_story", story: article.decorate, featured: article.main_image.present? %>
<% end %>
<%= javascript_packs_with_chunks_tag "followButtons", "feedPreviewCards", "hideBookmarkButtons", "localizeArticleDates", defer: true %>
<%= javascript_include_tag "followButtons", "feedPreviewCards", "hideBookmarkButtons", "localizeArticleDates", defer: true %>
<% else %>
<p><%= t("views.series.list.empty") %></p>
<% end %>

View file

@ -1,5 +1,5 @@
<div id="response-templates-data" class="hidden"></div>
<%= javascript_packs_with_chunks_tag "validateFileInputs", defer: true %>
<%= javascript_include_tag "validateFileInputs", defer: true %>
<% if @comment.errors.any? %>
<div class="crayons-notice crayons-notice--danger" role="alert">

View file

@ -1,5 +1,5 @@
<% title "Editing Comment" %>
<%= javascript_packs_with_chunks_tag "commentsDisplay", defer: true %>
<%= javascript_include_tag "commentsDisplay", defer: true %>
<div class="crayons-layout crayons-layout--limited-l gap-0">
<div
class="comments-container crayons-card min-w-0 text-padding"

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "postCommentsPage", defer: true %>
<%= javascript_include_tag "postCommentsPage", defer: true %>
<% if @root_comment.present? %>
<% title(@root_comment.title.to_s) %>
<% else %>
@ -44,7 +44,7 @@
<% end %>
<% end %>
<%= javascript_packs_with_chunks_tag "commentDropdowns", "followButtons", defer: true %>
<%= javascript_include_tag "commentDropdowns", "followButtons", defer: true %>
<div class="crayons-layout crayons-layout--limited-l gap-0" data-follow-button-container="true">
<% if @commentable && @commentable.class.name == "Article" %>
@ -89,7 +89,7 @@
</article>
<% else %>
<div id="response-templates-data" class="hidden"></div>
<%= javascript_packs_with_chunks_tag "commentsDisplay", defer: true %>
<%= javascript_include_tag "commentsDisplay", defer: true %>
<header class="p-2 pb-4 m:p-6 m:pb-6 crayons-card crayons-card--secondary crayons-layout__content s:mx-2 m:mx-4 -mb-1 z-0">
<% if @commentable %>
<h1 class="crayons-subtitle-1 mb-4">

View file

@ -105,4 +105,4 @@
<% end %>
<% end %>
</div>
<%= javascript_packs_with_chunks_tag "dashboardDropdowns", defer: true %>
<%= javascript_include_tag "dashboardDropdowns", defer: true %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "dashboardTags", defer: true %>
<%= javascript_include_tag "dashboardTags", defer: true %>
<div id="following-wrapper" class="grid gap-3 m:gap-4 s:grid-cols-2 l:grid-cols-3 px-3 m:px-0">
<% tags.each do |follow| %>

View file

@ -35,4 +35,4 @@
<%= render "shared/stats" %>
</main>
<%= javascript_packs_with_chunks_tag "analyticsDashboard", defer: true %>
<%= javascript_include_tag "analyticsDashboard", defer: true %>

View file

@ -36,7 +36,7 @@
</div>
<% if @articles.any? %>
<%= javascript_packs_with_chunks_tag "dashboardDropdowns", defer: true %>
<%= javascript_include_tag "dashboardDropdowns", defer: true %>
<div class="crayons-card mb-6 mt-3">
<% @articles.each do |article| %>
<% if params[:which] == "organization" %>
@ -68,5 +68,4 @@
</div>
</main>
<%= javascript_packs_with_chunks_tag "archivedPostFilters", defer: true %>
<%= javascript_packs_with_chunks_tag "dashboards/convertCoauthorIdsToUsernameInputs", defer: true %>
<%= javascript_include_tag "archivedPostFilters", "dashboards/convertCoauthorIdsToUsernameInputs", defer: true %>

View file

@ -4,7 +4,7 @@
<style>
<%= Rails.application.assets["setup-mode.css"].to_s.html_safe %>
</style>
<%= javascript_packs_with_chunks_tag "confirmationEmail", defer: true %>
<%= javascript_include_tag "confirmationEmail", defer: true %>
<div class="flex flex-1 flex-col items-center justify-center relative z-elevate align-center">
<%= render "devise/shared/error_messages", resource: resource %>

View file

@ -33,4 +33,4 @@
</li>
</ul>
</div>
<%= javascript_packs_with_chunks_tag "applyApplicationPolicyToggles", defer: true %>
<%= javascript_include_tag "applyApplicationPolicyToggles", defer: true %>

View file

@ -22,4 +22,4 @@
</div>
</div>
<%= javascript_packs_with_chunks_tag "signupModalShortcuts", defer: true %>
<%= javascript_include_tag "signupModalShortcuts", defer: true %>

View file

@ -12,7 +12,7 @@
<title><%= controller_name.titleize %></title>
<!-- StimulusJS -->
<%= javascript_packs_with_chunks_tag "admin", defer: true %>
<%= javascript_include_tag "admin", defer: true %>
<%= stylesheet_link_tag "admin" %>
@ -60,7 +60,7 @@
<%= render "admin/shared/nested_sidebar", menu_items: AdminMenu.navigation_items %>
</div>
<main id="main-content" class="crayons-layout__content min-w-0 p-2">
<%= javascript_packs_with_chunks_tag "admin/flashMessages", defer: true %>
<%= javascript_include_tag "admin/flashMessages", defer: true %>
<% flash.each_with_index do |(type, message), i| %>
<div
id="notice-container"

View file

@ -18,11 +18,9 @@
<% end %>
<meta name="environment" content="<%= Rails.env %>">
<%= render "layouts/styles", qualifier: "main" %>
<%= javascript_include_tag "base", defer: true %>
<%= javascript_include_tag "base", "application", "baseInitializers", "Search", "runtimeBanner", "baseTracking", defer: true %>
<% if user_signed_in? %>
<%= javascript_packs_with_chunks_tag "base", "baseInitializers", "Search", "runtimeBanner", "onboardingRedirectCheck", "contentDisplayPolicy", "baseTracking", defer: true %>
<% else %>
<%= javascript_packs_with_chunks_tag "base", "baseInitializers", "Search", "runtimeBanner", "baseTracking", defer: true %>
<%= javascript_include_tag "onboardingRedirectCheck", "contentDisplayPolicy", defer: true %>
<% end %>
<%= yield(:page_meta) %>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

View file

@ -67,7 +67,7 @@
</div>
<% unless @organizations.present? %>
<%= javascript_packs_with_chunks_tag "listingForm", defer: true %>
<%= javascript_include_tag "listingForm", defer: true %>
<% end %>
<div class="crayons-field">

View file

@ -7,5 +7,5 @@
data-orglistings="<%= @org_listings_json %>"
data-orgs="<%= @orgs_json %>">
</div>
<%= javascript_packs_with_chunks_tag "listingDashboard", defer: true %>
<%= javascript_include_tag "listingDashboard", defer: true %>
</main>

View file

@ -49,4 +49,4 @@
</div>
</main>
<%= javascript_packs_with_chunks_tag "listings", defer: true %>
<%= javascript_include_tag "listings", defer: true %>

View file

@ -31,7 +31,7 @@
<strong class="fs-2xl m:fs-3xl lh-tight color-base-90 m:mb-4 block" id="org-credits-number"><%= @organizations.first.credits.unspent.size %></strong>
<a id="org-credits-purchase-link" target="_blank" rel="noopener noreferrer" class="crayons-btn crayons-btn--secondary m:w-100" href="/credits/purchase?organization_id=<%= @organizations.first.id %>" data-no-instant><%= t("views.listings.new.buy") %></a>
</div>
<%= javascript_packs_with_chunks_tag "listingForm", "orgCreditsSelector", defer: true %>
<%= javascript_include_tag "listingForm", "orgCreditsSelector", defer: true %>
</div>
<% end %>

View file

@ -6,7 +6,7 @@
</style>
<% end %>
<%= javascript_packs_with_chunks_tag "actionsPanel", defer: true %>
<%= javascript_include_tag "actionsPanel", defer: true %>
<% author_suspended = @moderatable.user.suspended? %>
<% author_username = @moderatable.username %>

View file

@ -1,6 +1,6 @@
<% title t("views.moderations.heading") %>
<%= javascript_packs_with_chunks_tag "modCenter", defer: true %>
<%= javascript_include_tag "modCenter", defer: true %>
<div id="moderation-page" aria-hidden="true"></div>

View file

@ -1,6 +1,6 @@
<% title t("views.moderations.actions.meta.title2", title: @moderatable.title) %>
<%= javascript_packs_with_chunks_tag "commentModPage", defer: true %>
<%= javascript_include_tag "commentModPage", defer: true %>
<% cache(release_adjusted_cache_key("mod-styling")) do %>
<style>

View file

@ -16,7 +16,7 @@
<meta name="twitter:title" content="<%= t("views.notifications.meta.og.title", community: community_name) %>">
<meta name="twitter:description" content="<%= t("views.notifications.meta.description", community: community_name) %>">
<%= javascript_packs_with_chunks_tag "notificationPage", defer: true %>
<%= javascript_include_tag "notificationPage", defer: true %>
<% end %>
<script>
@ -67,7 +67,7 @@
</div>
<%= render "articles/fitvids" %>
</main>
<%= javascript_packs_with_chunks_tag "followButtons", "subscribeButton", defer: true %>
<%= javascript_include_tag "followButtons", "subscribeButton", defer: true %>
<script>
<%== RunkitTag.script %>
</script>

View file

@ -17,7 +17,7 @@
data-community-logo="<%= optimized_image_url(Settings::General.logo_png) %>"
data-community-background-color="<%= gradient_from_hex(Settings::UserExperience.primary_brand_color_hex)[:light] %>"
data-community-background-color2="<%= gradient_from_hex(Settings::UserExperience.primary_brand_color_hex)[:dark] %>">
<%= javascript_packs_with_chunks_tag "Onboarding", defer: true %>
<%= javascript_include_tag "Onboarding", defer: true %>
</div>
<div id="terms" style="display: none;">

View file

@ -26,4 +26,4 @@
</div>
</main>
<%= javascript_packs_with_chunks_tag "followButtons", defer: true %>
<%= javascript_include_tag "followButtons", defer: true %>

View file

@ -29,4 +29,4 @@
</main>
</div>
<%= javascript_packs_with_chunks_tag "storiesList", "followButtons", "hideBookmarkButtons", "localizeArticleDates", defer: true %>
<%= javascript_include_tag "storiesList", "followButtons", "hideBookmarkButtons", "localizeArticleDates", defer: true %>

View file

@ -98,4 +98,4 @@
</div>
</main>
<%= javascript_packs_with_chunks_tag "storiesList", "followButtons", defer: true %>
<%= javascript_include_tag "storiesList", "followButtons", defer: true %>

View file

@ -98,7 +98,7 @@
data-commentable-id="<%= @episode.id %>"
data-commentable-type="PodcastEpisode"
data-follow-button-container="true">
<%= javascript_packs_with_chunks_tag "commentDropdowns", defer: true %>
<%= javascript_include_tag "commentDropdowns", defer: true %>
<%= render "/comments/form",
commentable: @episode,
commentable_type: "PodcastEpisode" %>
@ -115,4 +115,4 @@
</main>
<%= render "podcast_episodes/podcast_bar", podcast: @podcast, episode: @episode %>
<%= javascript_packs_with_chunks_tag "followButtons", defer: true %>
<%= javascript_include_tag "followButtons", defer: true %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "validateFileInputs", defer: true %>
<%= javascript_include_tag "validateFileInputs", defer: true %>
<%= form_with(model: podcast, local: true) do |form| %>
<div>

View file

@ -19,4 +19,4 @@
<div id="reading-list" data-view="<%= @view %>"></div>
<%= javascript_packs_with_chunks_tag "readingList", defer: true %>
<%= javascript_include_tag "readingList", defer: true %>

View file

@ -33,4 +33,4 @@
<%= inline_svg_tag("preview-logo.svg", id: "color-select-preview-logo", class: "p-4 radius-default", title: t("views.logo.preview.icon")) %>
</div>
</div>
<%= javascript_packs_with_chunks_tag "enhanceColorPickers", defer: true %>
<%= javascript_include_tag "enhanceColorPickers", defer: true %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "foremCreatorSignup", defer: true %>
<%= javascript_include_tag "foremCreatorSignup", defer: true %>
<style>
#page-content {
display: flex;

View file

@ -61,4 +61,4 @@
<% end %>
</div>
<%= javascript_packs_with_chunks_tag "homePageFeedShortcuts", "feedPreviewCards", defer: true %>
<%= javascript_include_tag "homePageFeedShortcuts", "feedPreviewCards", defer: true %>

View file

@ -75,4 +75,4 @@
</div>
</main>
<%= javascript_packs_with_chunks_tag "searchParams", "storiesList", "followButtons", "feedPreviewCards", defer: true %>
<%= javascript_include_tag "searchParams", "storiesList", "followButtons", "feedPreviewCards", defer: true %>

View file

@ -16,7 +16,7 @@
</div>
<% end %>
<% if user_signed_in? %>
<%= javascript_packs_with_chunks_tag "sidebarWidget", defer: true %>
<%= javascript_include_tag "sidebarWidget", defer: true %>
<div id="sidebarWidget__pack" data-tag-info="<%= @tag.attributes.slice("id", "text_color_hex", "bg_color_hex", "name").to_json %>">
</div>
<% else %>

View file

@ -138,5 +138,5 @@
<%= render "stories/tagged_articles/sidebar_additional" %>
</div>
<%= javascript_packs_with_chunks_tag "storiesList", "followButtons", "tagFollows", "feedPreviewCards", "hideBookmarkButtons", "drawerSliders", "localizeArticleDates", defer: true %>
<%= javascript_include_tag "storiesList", "followButtons", "tagFollows", "feedPreviewCards", "hideBookmarkButtons", "drawerSliders", "localizeArticleDates", defer: true %>
<% end %>

View file

@ -56,4 +56,4 @@
</div>
<% end %>
</main>
<%= javascript_packs_with_chunks_tag "enhanceColorPickers", defer: true %>
<%= javascript_include_tag "enhanceColorPickers", defer: true %>

View file

@ -89,4 +89,4 @@
<% end %>
</main>
<%= javascript_packs_with_chunks_tag "tagFollows", defer: true %>
<%= javascript_include_tag "tagFollows", defer: true %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "stickySaveFooter", defer: true %>
<%= javascript_include_tag "stickySaveFooter", defer: true %>
<%= form_for @users_setting,
url: users_settings_path,

View file

@ -17,6 +17,6 @@
</div>
</div>
<%= javascript_packs_with_chunks_tag "githubRepos", defer: true %>
<%= javascript_include_tag "githubRepos", defer: true %>
</div>
<% end %>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "validateFileInputs", defer: true %>
<%= javascript_include_tag "validateFileInputs", defer: true %>
<div class="crayons-card crayons-card--content-rows">
<h2><%= t("views.settings.org.join.heading") %></h2>

View file

@ -1,4 +1,4 @@
<%= javascript_packs_with_chunks_tag "enhanceColorPickers", "stickySaveFooter", "userProfileSettings", "validateFileInputs", defer: true %>
<%= javascript_include_tag "enhanceColorPickers", "stickySaveFooter", "userProfileSettings", "validateFileInputs", defer: true %>
<%= render "users/additional_authentication" %>

View file

@ -150,7 +150,7 @@
</div>
</main>
<%= javascript_packs_with_chunks_tag "storiesList", "followButtons",
<%= javascript_include_tag "storiesList", "followButtons",
"feedPreviewCards", "hideBookmarkButtons",
"profileDropdown", "users/profilePage",
"localizeArticleDates", "asyncUserStatusCheck",

View file

@ -37,7 +37,6 @@ module.exports = function (api) {
plugins: [
isEndToEnd && ['istanbul'],
'@babel/plugin-syntax-dynamic-import',
isTestEnv && 'babel-plugin-dynamic-import-node',
isTestEnv && '@babel/plugin-transform-modules-commonjs',
'@babel/plugin-transform-destructuring',
[

11
bin/dev Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env sh
if ! gem list foreman -i --silent; then
echo "Installing foreman..."
gem install foreman
fi
# Default to port 3000 if not specified
export PORT="${PORT:-3000}"
exec foreman start -f Procfile.dev "$@"

View file

@ -1,19 +0,0 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"
ENV["NODE_OPTIONS"] ||= "--openssl-legacy-provider"
require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require "bundler/setup"
require "webpacker"
require "webpacker/webpack_runner"
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Webpacker::WebpackRunner.run(ARGV)
end

View file

@ -1,19 +0,0 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"
ENV["NODE_OPTIONS"] ||= "--openssl-legacy-provider"
require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require "bundler/setup"
require "webpacker"
require "webpacker/dev_server_runner"
APP_ROOT = File.expand_path("..", __dir__)
Dir.chdir(APP_ROOT) do
Webpacker::DevServerRunner.run(ARGV)
end

View file

@ -43,7 +43,7 @@ Rails.application.configure do
}
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglify_with_source_maps
config.assets.js_compressor = :terser
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.

View file

@ -12,12 +12,6 @@ Rails.application.config.content_security_policy do |policy|
# policy.script_src :self, :https
# policy.style_src :self, :https
# If you are using webpack-dev-server then specify webpack-dev-server host
if Rails.env.development?
webpack_host = "#{ApplicationConfig.app_domain_no_port}:3035"
policy.connect_src :self, :https, "http://#{webpack_host}", "ws://#{webpack_host}"
end
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
end

View file

@ -1,51 +0,0 @@
require "sprockets/digest_utils"
require "sprockets/uglifier_compressor"
module Sprockets
class UglifierWithSourceMapsCompressor < Sprockets::UglifierCompressor
def call(input)
data = input.fetch(:data) # Non-Uglified contents of the JS file
name = input.fetch(:name) # name of the to-be-compressed JS file.
@uglifier ||= Autoload::Uglifier.new(@options.merge({ harmony: true }))
compressed_data, sourcemap_json = @uglifier.compile_with_map(input[:data])
# Update source map according to the version 3 spec: https://sourcemaps.info/spec.html
sourcemap = JSON.parse(sourcemap_json)
sourcemap["sources"] = ["#{name}.js"]
sourcemap["sourceRoot"] = ::Rails.application.config.assets.prefix
sourcemap["sourcesContent"] = [data]
sourcemap_json = sourcemap.to_json
sourcemap_filename = File.join(
::Rails.application.config.assets.prefix,
"#{name}-#{digest(sourcemap_json)}.js.map",
)
# rubocop:disable Rails/RootPathnameMethods
sourcemap_path = File.join(::Rails.public_path, sourcemap_filename)
# rubocop:enable Rails/RootPathnameMethods
sourcemap_url = filename_to_url(sourcemap_filename)
FileUtils.mkdir_p File.dirname(sourcemap_path)
File.write(sourcemap_path, sourcemap_json)
# Add the source map URL to the compressed JS file.
compressed_data.concat "\n//# sourceMappingURL=#{sourcemap_url}\n"
end
def filename_to_url(filename)
url_root = ::Rails.application.config.assets.source_maps_domain
File.join url_root.to_s, filename
end
def digest(io)
Sprockets::DigestUtils.pack_hexdigest Sprockets::DigestUtils.digest(io)
end
end
end
Sprockets.register_compressor(
"application/javascript",
:uglify_with_source_maps,
Sprockets::UglifierWithSourceMapsCompressor,
)

View file

@ -1,27 +0,0 @@
/* eslint-env node */
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const environment = require('./environment');
const config = environment.toWebpackConfig();
// For more information, see https://webpack.js.org/configuration/devtool/#devtool
config.devtool = 'eval-source-map';
// Inject the preact/debug import into all the webpacker pack files (webpack entry points) that reference at least one Preact component
// so that Preact components can be debugged with the Preact DevTools.
config.entry = Object.entries(config.entry).reduce(
(previous, [entryPointName, entryPointFileName]) => {
if (/\.jsx$/.test(entryPointFileName)) {
previous[entryPointName] = ['preact/debug', entryPointFileName];
} else {
previous[entryPointName] = entryPointFileName;
}
return previous;
},
{},
);
module.exports = config;

View file

@ -1,61 +0,0 @@
/* eslint-env node */
const path = require('path');
const { environment } = require('@rails/webpacker');
const HoneybadgerSourceMapPlugin = require('@honeybadger-io/webpack');
const erb = require('./loaders/erb');
/*
The customizations below are to create the vendor chunk. The vendor chunk is no longer consumed like it was in webpacker 3.
There is no longer one vendor bundle. It gets code split based on what webpacker packs need. All the object spreading e.g. `...config.optimization` is to keep
the existing configuration and only override/add what is necessary.
The cache groups section is the default cache groups in webpack 4. See https://webpack.js.org/plugins/split-chunks-plugin/#optimizationsplitchunks.
It does not appear to be the default with webpacker 4.
*/
environment.splitChunks((config) => {
return {
...config,
resolve: {
...config.resolve,
alias: {
...(config.resolve ? config.resolve.alias : {}),
'@crayons': path.resolve(__dirname, '../../app/javascript/crayons'),
'@utilities': path.resolve(__dirname, '../../app/javascript/utilities'),
'@images': path.resolve(__dirname, '../../app/assets/images'),
'@admin': path.resolve(__dirname, '../../app/javascript/admin'),
'@components': path.resolve(
__dirname,
'../../app/javascript/shared/components',
),
react: 'preact/compat',
'react-dom': 'preact/compat',
},
},
};
});
environment.config.output.hashFunction = 'sha256';
// We don't want babel-loader running on the node_modules folder.
environment.loaders.delete('nodeModules');
environment.loaders.append('erb', erb);
if (process.env.HONEYBADGER_API_KEY && process.env.ASSETS_URL) {
environment.plugins.append(
'HoneybadgerSourceMap',
new HoneybadgerSourceMapPlugin({
apiKey: process.env.HONEYBADGER_API_KEY,
assetsUrl: process.env.ASSETS_URL,
silent: false,
ignoreErrors: false,
revision:
process.env.RELEASE_FOOTPRINT ||
process.env.HEROKU_SLUG_COMMIT ||
'main',
}),
);
}
module.exports = environment;

View file

@ -1,16 +0,0 @@
/* eslint-env node */
module.exports = {
test: /\.erb$/,
enforce: 'pre',
exclude: /node_modules/,
use: [
{
loader: 'rails-erb-loader',
options: {
runner:
(/^win/.test(process.platform) ? 'ruby ' : '') + 'bin/rails runner',
},
},
],
};

View file

@ -1,7 +0,0 @@
/* eslint-env node */
process.env.NODE_ENV = process.env.NODE_ENV || 'production';
const environment = require('./environment');
module.exports = environment.toWebpackConfig();

View file

@ -1,11 +0,0 @@
/* eslint-env node */
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const environment = require('./environment');
const config = environment.toWebpackConfig();
config.stats = 'errors-only';
module.exports = config;

View file

@ -1,93 +0,0 @@
# Note: You must restart bin/webpack-dev-server for changes to take effect
default: &default
source_path: app/javascript
source_entry_path: packs
public_root_path: public
public_output_path: packs
cache_path: tmp/cache/webpacker
webpack_compile_output: true
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: ['app/assets']
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
# Extract and emit a css file
extract_css: false
static_assets_extensions:
- .jpg
- .jpeg
- .png
- .gif
- .tiff
- .ico
- .svg
- .eot
- .otf
- .ttf
- .woff
- .woff2
extensions:
- .mjs
- .erb
- .js
- .jsx
- .sass
- .scss
- .css
- .module.sass
- .module.scss
- .module.css
- .png
- .svg
- .gif
- .jpeg
- .jpg
development:
<<: *default
compile: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
host: 0.0.0.0
port: 3035
public: 0.0.0.0:3035
hmr: false
# Inline should be set to true if using HMR
inline: true
overlay: true
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
pretty: false
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: '**/node_modules/**'
test:
<<: *default
compile: true
# Compile test packs to a separate directory
public_output_path: packs-test
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Extract and emit a css file
extract_css: true
# Cache manifest.json for performance
cache_manifest: true

View file

@ -18,16 +18,20 @@ describe('Follow podcast', () => {
'followButton',
);
cy.intercept('/follows').as('followRequest');
cy.get('@followButton').should('have.text', 'Follow');
cy.get('@followButton').click();
// Inner text should now be following
cy.wait('@followRequest');
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
// Check that state is persisted on refresh
cy.visitAndWaitForUserSideEffects('/developeronfire');
cy.reload()
cy.findByRole('button', { name: 'Follow podcast: Developer on Fire' }).as(
'followButton',
);
cy.get('@followButton').should('have.text', 'Following');
cy.get('@followButton').should('have.attr', 'aria-pressed', 'true');
// Check it reverts back to Follow on click

View file

@ -23,8 +23,7 @@ x-backend: &backend
- rails_cache:/app/tmp/cache
- assets:/app/public/assets
- node_modules:/app/node_modules
- packs:/app/public/packs
- packs-test:/app/public/packs-test
- builds:/app/public/builds
- history:/usr/local/hist
- ${LOCAL_WORKSPACE_FOLDER:-.}/.dockerdev/.psqlrc:/root/.psqlrc:ro
environment: &backend_environment
@ -33,7 +32,6 @@ x-backend: &backend
REDIS_URL: redis://redis:6379/
DATABASE_URL: postgres://postgres:postgres@postgres:5432
DATABASE_URL_TEST: postgres://postgres:postgres@postgres:5432
WEBPACKER_DEV_SERVER_HOST: webpacker
MALLOC_ARENA_MAX: 2
WEB_CONCURRENCY: ${WEB_CONCURRENCY:-1}
BOOTSNAP_CACHE_DIR: /usr/local/bundle/_bootsnap
@ -65,8 +63,7 @@ services:
- rails_cache:/workspaces/forem/tmp/cache
- assets:/workspaces/forem/public/assets
- node_modules:/workspaces/forem/node_modules
- packs:/workspaces/forem/public/packs
- packs-test:/workspaces/forem/public/packs-test
- builds:/workspaces/forem/app/assets/builds
- history:/usr/local/hist
- ${LOCAL_WORKSPACE_FOLDER:-.}/.dockerdev/.psqlrc:/root/.psqlrc:ro
- /var/run/docker.sock:/var/run/docker-host.sock
@ -86,7 +83,7 @@ services:
ports:
- '3000:3000'
depends_on:
webpacker:
esbuild:
condition: service_started
sidekiq:
condition: service_started
@ -122,17 +119,14 @@ services:
timeout: 3s
retries: 30
webpacker:
esbuild:
<<: *app
command: bundle exec ./bin/webpack-dev-server
ports:
- '3035:3035'
command: yarn build --watch
volumes:
- ${LOCAL_WORKSPACE_FOLDER:-.}:/app:cached
- bundle:/usr/local/bundle
- node_modules:/app/node_modules
- packs:/app/public/packs
- packs-test:/app/public/packs-test
- builds:/app/assets/builds
environment:
<<: *env
WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
@ -166,6 +160,5 @@ volumes:
postgres:
redis:
assets:
packs:
packs-test:
builds:

39
esbuild.config.mjs Normal file
View file

@ -0,0 +1,39 @@
import * as esbuild from 'esbuild'
import glob from 'glob'
import svgr from 'esbuild-plugin-svgr'
import { stimulusPlugin } from 'esbuild-plugin-stimulus'
let ctx = {
loader: {
'.js': 'jsx',
'.jsx': 'jsx',
'.png': 'file',
},
target: ['es2019'],
entryPoints: glob.sync("app/javascript/packs/**/*.*"),
jsxFactory: 'h',
jsxFragment: 'Fragment',
bundle: true,
minify: true,
sourcemap: false,
outdir: 'app/assets/builds',
logLevel: 'info',
define: {
'global': 'window',
},
alias: {
'react': 'preact/compat',
'react-dom': 'preact/compat',
},
plugins: [
svgr({jsxRuntime: 'classic-preact' }),
stimulusPlugin(),
],
}
if (process.argv.includes('--watch')) {
ctx = await esbuild.context(ctx)
await ctx.watch()
} else {
await esbuild.build(ctx)
}

View file

@ -1,13 +1,14 @@
{
"compilerOptions": {
"baseUrl": "./",
"baseUrl": ".",
"paths": {
"@crayons/*": ["app/javascript/crayons/*"],
"@utilities/*": ["app/javascript/utilities/*"],
"@images/*": ["app/assets/images/*"],
"@components/*": ["app/javascript/shared/components/*"],
"@admin/*": ["app/javascript/admin/*"]
"@crayons*": ["./app/javascript/crayons/*"],
"@utilities/*": ["./app/javascript/utilities/*"],
"@images*": ["./app/assets/images/*"],
"@components*": ["./app/javascript/shared/components/*"],
"@admin*": ["./app/javascript/admin/*"]
}
},
"exclude": ["node_modules", "**/node_modules/*"]
"include": ["./app/javascript/**/*"],
"exclude": ["node_modules", "public"]
}

View file

@ -26,7 +26,8 @@
"test:watch": "jest app/javascript/ bin/ --watch",
"postcss": "postcss public/assets/*.css -d public/assets",
"e2e": "bin/e2e",
"e2e:creator-onboarding-seed": "yarn run e2e --creator-onboarding-seed"
"e2e:creator-onboarding-seed": "yarn run e2e --creator-onboarding-seed",
"build": "node esbuild.config.mjs"
},
"nyc": {
"report-dir": "coverage/cypress"
@ -102,8 +103,7 @@
"sass-loader": "^13.3.2",
"storybook-addon-jsx": "^7.3.14",
"style-loader": "^2.0.0",
"svgo": "2.8.0",
"webpack-dev-server": "^3.11.3"
"svgo": "2.8.0"
},
"dependencies": {
"@babel/core": "^7.23.3",
@ -115,11 +115,8 @@
"@babel/preset-env": "^7.23.3",
"@babel/preset-typescript": "^7.23.3",
"@honeybadger-io/js": "^5.4.1",
"@honeybadger-io/webpack": "^1.5.1",
"@hotwired/stimulus": "3.2.2",
"@hotwired/stimulus-webpack-helpers": "1.0.1",
"@rails/ujs": "7.1.2",
"@rails/webpacker": "5.4.4",
"ahoy.js": "^0.4.3",
"autoprefixer": "^10.4.16",
"babel-plugin-inline-react-svg": "^2.0.2",
@ -129,6 +126,9 @@
"chart.js": "^3.9.1",
"classnames": "^2.3.2",
"core-js": "3",
"esbuild": "^0.19.10",
"esbuild-plugin-stimulus": "^0.1.5",
"esbuild-plugin-svgr": "^2.1.0",
"file-loader": "^6.2.0",
"focus-trap": "^6.9.4",
"focus-visible": "^5.2.0",
@ -142,6 +142,7 @@
"moment": "^2.29.4",
"postcss": "^8.4.31",
"postcss-cli": "^10.1.0",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^15.1.0",
"postcss-preset-env": "^7.8.2",
"postscribe": "^2.0.8",

BIN
vendor/cache/jsbundling-rails-1.2.1.gem vendored Normal file

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more