Merge pull request #7469 from tchak/use-vite-again

Use vitejs
This commit is contained in:
Paul Chavard 2022-06-23 15:47:45 +02:00 committed by GitHub
commit 9dc96e505a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
51 changed files with 1230 additions and 4523 deletions

View file

@ -1,10 +0,0 @@
> 1%
Chrome >= 50
Edge >= 14
Firefox >= 50
Opera >= 40
Safari >= 8
iOS >= 8
# Although IE 11 shows a deprecation banner, we still support the transpilation option.
# IE 11 support will be removed on Jan. 31st, 2021.
IE >= 11

View file

@ -1,10 +1,6 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2017,
sourceType: 'module'
},
parser: '@typescript-eslint/parser',
globals: {
process: true,
gon: true
@ -27,25 +23,15 @@ module.exports = {
'react/prop-types': 'off'
},
settings: {
react: {
version: 'detect'
}
react: { version: 'detect' }
},
overrides: [
{
files: [
'.eslintrc.js',
'config/webpack/**/*.js',
'babel.config.js',
'postcss.config.js'
],
env: {
node: true
}
files: ['.eslintrc.js', 'vite.config.ts'],
env: { node: true }
},
{
files: ['**/*.ts', '**/*.tsx'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',

View file

@ -105,7 +105,7 @@ jobs:
run: |
SPEC_FILES=$(./split_tests -glob='spec/system/**/*_spec.rb' -split-index=${{ strategy.job-index }} -split-total=${{ strategy.job-total }} -junit -junit-path=tmp/*.junit.xml)
echo "Running tests for bin/rspec $SPEC_FILES"
bin/rspec $SPEC_FILES --format progress --format RspecJunitFormatter --out tmp/rspec_${{ github.job }}_${{ strategy.job-index }}.junit.xml
RAILS_ENV=test bin/rspec $SPEC_FILES --format progress --format RspecJunitFormatter --out tmp/rspec_${{ github.job }}_${{ strategy.job-index }}.junit.xml
- name: Upload test results for this instance
uses: actions/upload-artifact@v2

11
.gitignore vendored
View file

@ -19,10 +19,7 @@ doc/*.svg
uploads/*
.byebug_history
.env
Procfile.dev
storage/
/public/packs
/public/packs-test
/node_modules
/yarn-error.log
yarn-debug.log*
@ -42,3 +39,11 @@ yarn-debug.log*
# Custom views
/app/custom_views/*
!/app/custom_views/.keep
# Webpacker
public/packs
public/packs-test
# Vite Ruby
public/vite
public/vite-dev
public/vite-test

View file

@ -86,8 +86,9 @@ gem 'strong_migrations' # lint database migrations
gem 'turbo-rails'
gem 'typhoeus'
gem 'view_component'
gem 'vite_plugin_legacy'
gem 'vite_rails'
gem 'warden'
gem 'webpacker'
gem 'zipline'
gem 'zxcvbn-ruby', require: 'zxcvbn'

View file

@ -218,6 +218,7 @@ GEM
dotenv-rails (2.7.6)
dotenv (= 2.7.6)
railties (>= 3.2)
dry-cli (0.7.0)
dry-inflector (0.2.0)
dumb_delegator (1.0.0)
ecma-re-validator (0.3.0)
@ -426,7 +427,7 @@ GEM
mini_magick (4.11.0)
mini_mime (1.1.2)
mini_portile2 (2.8.0)
minitest (5.15.0)
minitest (5.16.0)
momentjs-rails (2.20.1)
railties (>= 3.1)
msgpack (1.4.2)
@ -516,7 +517,7 @@ GEM
rack (>= 2.1.0)
rack-protection (2.2.0)
rack
rack-proxy (0.7.0)
rack-proxy (0.7.2)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
@ -547,7 +548,7 @@ GEM
activesupport (>= 4.2)
choice (~> 0.2.0)
ruby-graphviz (~> 1.2)
rails-html-sanitizer (1.4.2)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
rails-i18n (7.0.3)
i18n (>= 0.7, < 2)
@ -662,7 +663,6 @@ GEM
selenium-webdriver (3.142.7)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
semantic_range (3.0.0)
sentry-delayed_job (4.8.1)
delayed_job (>= 4.0)
sentry-ruby-core (~> 4.8.1)
@ -749,6 +749,15 @@ GEM
axiom-types (~> 0.1)
coercible (~> 1.0)
descendants_tracker (~> 0.0, >= 0.0.3)
vite_plugin_legacy (3.0.2)
vite_ruby (~> 3.0, >= 3.0.4)
vite_rails (3.0.9)
railties (>= 5.1, < 8)
vite_ruby (~> 3.0)
vite_ruby (3.1.6)
dry-cli (~> 0.7.0)
rack-proxy (~> 0.6, >= 0.6.1)
zeitwerk (~> 2.2)
warden (1.2.9)
rack (>= 2.0.9)
watir (6.19.1)
@ -770,17 +779,12 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (5.4.3)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
semantic_range (>= 2.3.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.5.4)
zeitwerk (2.6.0)
zip_tricks (5.6.0)
zipline (1.4.1)
actionpack (>= 6.0, < 8.0)
@ -908,11 +912,12 @@ DEPENDENCIES
typhoeus
vcr
view_component
vite_plugin_legacy
vite_rails
warden
web-console
webdrivers (~> 4.0)
webmock
webpacker
zipline
zxcvbn-ruby

View file

@ -1,2 +0,0 @@
server: RAILS_QUEUE_ADAPTER=delayed_job bin/rails server -p 3000
jobs: bin/rake jobs:work

3
Procfile.dev Normal file
View file

@ -0,0 +1,3 @@
web: RAILS_QUEUE_ADAPTER=delayed_job bin/rails server -p 3000
jobs: bin/rake jobs:work
vite: bin/vite dev

View file

@ -55,16 +55,9 @@ Afin d'initialiser l'environnement de développement, exécutez la commande suiv
On lance le serveur d'application ainsi :
bin/rails server
bin/dev
L'application tourne alors à l'adresse `http://localhost:3000`, et utilise le mécanisme par défaut de rails pour les tâches asynchrones.
C'est ce qu'on veut dans la plupart des cas. Une exception: ça ne joue pas les tâches cron.
Pour être une peu plus proche du comportement de production, et jouer les tâches cron, on peut lancer la message queue
dans un service dédié, et indiquer à rails d'utiliser delayed_job:
bin/rake jobs:work
RAILS_QUEUE_ADAPTER=delayed_job bin/rails server
L'application tourne alors à l'adresse `http://localhost:3000` en parralel avec un worker pour les jobs et le bundler vitejs.
### Utilisateurs de test

View file

@ -181,4 +181,12 @@ module ApplicationHelper
def show_outdated_browser_banner?
!supported_browser? && !has_dismissed_outdated_browser_banner?
end
def vite_legacy?
if ENV['VITE_LEGACY'] == 'disabled'
false
else
Rails.env.production? || ENV['VITE_LEGACY'] == 'enabled'
end
end
end

View file

@ -0,0 +1,2 @@
import Component from './MapEditor/index';
export default Component;

View file

@ -0,0 +1,2 @@
import Component from './MapReader/index';
export default Component;

View file

@ -1,6 +0,0 @@
import 'trix';
import '@rails/actiontext';
export default function () {
return null;
}

View file

@ -1,12 +1,25 @@
import Chartkick from 'chartkick';
import Highcharts from 'highcharts';
import { Controller } from '@hotwired/stimulus';
import { toggle, delegate } from '@utils';
export default function () {
return null;
export class ChartkickController extends Controller {
async connect() {
const Highcharts = await import('highcharts');
const Chartkick = await import('chartkick');
Chartkick.use(Highcharts);
const reflow = (nextChartId?: string) =>
nextChartId && Chartkick.charts[nextChartId]?.getChartObject()?.reflow();
delegate('click', '[data-toggle-chart]', (event) =>
toggleChart(event as MouseEvent, reflow)
);
}
}
function toggleChart(event: MouseEvent) {
function toggleChart(
event: MouseEvent,
reflow: (nextChartId?: string) => void
) {
const nextSelectorItem = event.target as HTMLButtonElement,
chartClass = nextSelectorItem.dataset.toggleChart,
nextChart = chartClass
@ -30,9 +43,5 @@ function toggleChart(event: MouseEvent) {
nextChart && toggle(nextChart);
// Reflow needed, see https://github.com/highcharts/highcharts/issues/1979
nextChartId && Chartkick.charts[nextChartId]?.getChartObject()?.reflow();
reflow(nextChartId);
}
delegate('click', '[data-toggle-chart]', toggleChart);
Chartkick.use(Highcharts);

View file

@ -1,32 +0,0 @@
import { Application } from '@hotwired/stimulus';
import { AutofocusController } from './autofocus_controller';
import { AutosaveController } from './autosave_controller';
import { AutosaveStatusController } from './autosave_status_controller';
import { GeoAreaController } from './geo_area_controller';
import { MenuButtonController } from './menu_button_controller';
import { PersistedFormController } from './persisted_form_controller';
import { ReactController } from './react_controller';
import { ScrollToController } from './scroll_to_controller';
import { SortableController } from './sortable_controller';
import { TurboEventController } from './turbo_event_controller';
import { TurboInputController } from './turbo_input_controller';
import { TurboPollController } from './turbo_poll_controller';
import { TypeDeChampEditorController } from './type_de_champ_editor_controller';
import { IBANInputController } from './iban_input_controller';
const Stimulus = Application.start();
Stimulus.register('autofocus', AutofocusController);
Stimulus.register('autosave-status', AutosaveStatusController);
Stimulus.register('autosave', AutosaveController);
Stimulus.register('geo-area', GeoAreaController);
Stimulus.register('menu-button', MenuButtonController);
Stimulus.register('persisted-form', PersistedFormController);
Stimulus.register('react', ReactController);
Stimulus.register('scroll-to', ScrollToController);
Stimulus.register('sortable', SortableController);
Stimulus.register('turbo-event', TurboEventController);
Stimulus.register('turbo-input', TurboInputController);
Stimulus.register('turbo-poll', TurboPollController);
Stimulus.register('type-de-champ-editor', TypeDeChampEditorController);
Stimulus.register('iban-input', IBANInputController);

View file

@ -6,11 +6,18 @@ import invariant from 'tiny-invariant';
type Props = Record<string, unknown>;
type Loader = () => Promise<{ default: FunctionComponent<Props> }>;
const componentsRegistry = new Map<string, FunctionComponent<Props>>();
const components = import.meta.glob('../components/*.tsx');
export function registerComponents(components: Record<string, Loader>): void {
for (const [className, loader] of Object.entries(components)) {
componentsRegistry.set(className, LoadableComponent(loader));
}
for (const [path, loader] of Object.entries(components)) {
const [filename] = path.split('/').reverse();
const componentClassName = filename.replace(/\.(ts|tsx)$/, '');
console.debug(
`Registered lazy default export for "${componentClassName}" component`
);
componentsRegistry.set(
componentClassName,
LoadableComponent(loader as Loader)
);
}
// Initialize React components when their markup appears into the DOM.

View file

@ -0,0 +1,8 @@
import { Controller } from '@hotwired/stimulus';
export class TrixController extends Controller {
connect() {
import('trix');
import('@rails/actiontext');
}
}

View file

@ -1,8 +1,8 @@
import '../shared/polyfills';
import Rails from '@rails/ujs';
import * as ActiveStorage from '@rails/activestorage';
import 'whatwg-fetch'; // window.fetch polyfill
import * as Turbo from '@hotwired/turbo';
import { Application } from '@hotwired/stimulus';
import '../shared/activestorage/ujs';
import '../shared/remote-poller';
@ -10,8 +10,7 @@ import '../shared/safari-11-file-xhr-workaround';
import '../shared/toggle-target';
import '../shared/ujs-error-handling';
import { registerComponents } from '../controllers/react_controller';
import '../controllers';
import { registerControllers } from '../shared/stimulus-loader';
import '../new_design/form-validation';
import '../new_design/procedure-context';
@ -41,23 +40,8 @@ import {
showNewAccountPasswordConfirmation
} from '../new_design/fc-fusion';
registerComponents({
Chartkick: () => import('../components/Chartkick'),
ComboAdresseSearch: () => import('../components/ComboAdresseSearch'),
ComboAnnuaireEducationSearch: () =>
import('../components/ComboAnnuaireEducationSearch'),
ComboCommunesSearch: () => import('../components/ComboCommunesSearch'),
ComboDepartementsSearch: () =>
import('../components/ComboDepartementsSearch'),
ComboMultipleDropdownList: () =>
import('../components/ComboMultipleDropdownList'),
ComboMultiple: () => import('../components/ComboMultiple'),
ComboPaysSearch: () => import('../components/ComboPaysSearch'),
ComboRegionsSearch: () => import('../components/ComboRegionsSearch'),
MapEditor: () => import('../components/MapEditor'),
MapReader: () => import('../components/MapReader'),
Trix: () => import('../components/Trix')
});
const application = Application.start();
registerControllers(application);
// This is the global application namespace where we expose helpers used from rails views
const DS = {
@ -75,9 +59,11 @@ const DS = {
};
// Start Rails helpers
Rails.start();
ActiveStorage.start();
Turbo.session.drive = false;
// Expose globals
window.DS = window.DS || DS;
import('../shared/track/matomo');
import('../shared/track/sentry');

View file

@ -1,2 +0,0 @@
import '../shared/track/matomo';
import '../shared/track/sentry';

View file

@ -1,19 +1,3 @@
// Include runtime-polyfills for older browsers.
// Due to babel.config.js's 'useBuiltIns', only polyfills actually
// required by the browsers we support will be included.
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import 'dom4';
import 'intersection-observer';
import 'whatwg-fetch';
import '@webcomponents/custom-elements';
import '@webcomponents/template';
import '@stimulus/polyfills';
import 'formdata-polyfill';
import 'event-target-polyfill';
import 'yet-another-abortcontroller-polyfill';
import './polyfills/insertAdjacentElement';
import './polyfills/dataset';
// IE 11 has no baseURI (required by turbo)

View file

@ -1,47 +0,0 @@
/*
Updated w/ insertAdjacentElement
@author Dan Levy @justsml
2016-06-23
Credit: @lyleunderwood - afterend patch/fix
2011-10-10
By Eli Grey, http://eligrey.com
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
function insertAdjacentElement(position, elem) {
const _this = this;
const parent = this.parentNode;
let node, first;
switch (position.toLowerCase()) {
case 'beforebegin':
while ((node = elem.firstChild)) {
parent.insertBefore(node, _this);
}
break;
case 'afterbegin':
first = _this.firstChild;
while ((node = elem.lastChild)) {
first = _this.insertBefore(node, first);
}
break;
case 'beforeend':
while ((node = elem.firstChild)) {
_this.appendChild(node);
}
break;
case 'afterend':
parent.insertBefore(elem, _this.nextSibling);
break;
}
return elem;
}
// Method missing in Firefox < 48
if (!HTMLElement.prototype.insertAdjacentElement) {
HTMLElement.prototype.insertAdjacentElement = insertAdjacentElement;
}

View file

@ -0,0 +1,30 @@
import { Application } from '@hotwired/stimulus';
import invariant from 'tiny-invariant';
const controllers = import.meta.globEager('../controllers/*.{ts,tsx}');
export function registerControllers(application: Application) {
for (const [path, mod] of Object.entries(controllers)) {
const [filename] = path.split('/').reverse();
const name = filename
.replace(/_/g, '-')
.replace(/-controller\.(ts|tsx)$/, '');
if (name != 'application') {
if (mod.default) {
console.debug(`Registered default export for "${name}" controller`);
application.register(name, mod.default);
} else {
const exports = Object.entries(mod);
invariant(
exports.length == 1,
`Expected a single export but ${exports.length} exports were found for "${name}" controller`
);
const [exportName, exportMod] = exports[0];
console.debug(
`Registered named export "${exportName}" for "${name}" controller`
);
application.register(name, exportMod);
}
}
}
}

View file

@ -22,3 +22,5 @@ declare module '@tmcw/togeojson/dist/togeojson.es.js' {
declare module 'react-coordinate-input';
declare module 'chartkick';
declare module 'trix';
declare module '@rails/actiontext';

View file

@ -1,6 +1,5 @@
class BrowserSupport
def self.supported?(browser)
# See .browserslistrc
[
browser.chrome? && browser.version.to_i >= 50 && !browser.platform.ios?,
browser.edge? && browser.version.to_i >= 14 && !browser.compatibility_view?,

View file

@ -1,7 +1,3 @@
-# Load Trix lazily, by using our React lazy-loader.
-# (Trix itself doesn't use React though)
= react_component('Trix')
= f.label :subject do
Objet de l'email
%span.mandatory *
@ -12,7 +8,7 @@
%span.mandatory *
= f.rich_text_area :rich_body, required: true, class: "mb-4"
#tags-table
#tags-table{ 'data-controller': 'trix' }
%h2.add-tag-title
Insérer une balise
%p.notice

View file

@ -13,8 +13,11 @@
= favicon_link_tag(image_url("#{FAVICON_32PX_SRC}"), type: "image/png", sizes: "32x32")
= favicon_link_tag(image_url("#{FAVICON_96PX_SRC}"), type: "image/png", sizes: "96x96")
- packs = ['application', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact
= javascript_packs_with_chunks_tag *packs, defer: true
= vite_client_tag
= vite_react_refresh_tag
= vite_javascript_tag 'application'
- if administrateur_signed_in?
= vite_javascript_tag 'track-admin'
= preload_link_tag(asset_url("Muli-Regular.woff2"))
= preload_link_tag(asset_url("Muli-Bold.woff2"))
@ -40,6 +43,9 @@
- if content_for?(:footer)
= content_for(:footer)
- if vite_legacy?
= vite_legacy_javascript_tag 'application'
= yield :charts_js
// Container for custom turbo-stream actions

View file

@ -11,7 +11,7 @@ by providing a `content_for(:javascript)` block.
<%= javascript_include_tag js_path %>
<% end %>
<%= javascript_packs_with_chunks_tag 'manager' %>
<%= vite_javascript_tag 'manager' %>
<%= yield :javascript %>

View file

@ -1,8 +1,4 @@
.statistiques
-# Load Chartkick lazily, by using our React lazy-loader.
-# (Chartkick itself doesn't use React though)
= react_component('Chartkick')
.statistiques{ 'data-controller': 'chartkick' }
%h1.new-h1= title
.stat-cards
- if @usual_traitement_time.present?

View file

@ -2,11 +2,7 @@
- content_for :footer do
= render partial: "root/footer"
.statistiques
-# Load Chartkick lazily, by using our React lazy-loader.
-# (Chartkick itself doesn't use React though)
= react_component('Chartkick')
.statistiques{ 'data-controller': 'chartkick' }
%h1.new-h1 Statistiques
.stat-cards

View file

@ -1,92 +0,0 @@
module.exports = function (api) {
var validEnv = ['development', 'test', 'production'];
var currentEnv = api.env();
var isDevelopmentEnv = api.env('development');
var isProductionEnv = api.env('production');
var isTestEnv = api.env('test');
if (!validEnv.includes(currentEnv)) {
throw new Error(
'Please specify a valid `NODE_ENV` or ' +
'`BABEL_ENV` environment variables. Valid values are "development", ' +
'"test", and "production". Instead, received: ' +
JSON.stringify(currentEnv) +
'.'
);
}
return {
presets: [
isTestEnv && [
'@babel/preset-env',
{
targets: {
node: 'current'
}
}
],
(isProductionEnv || isDevelopmentEnv) && [
'@babel/preset-env',
{
forceAllTransforms: true,
useBuiltIns: 'usage',
corejs: 3,
modules: false,
exclude: ['transform-typeof-symbol']
}
],
[
'@babel/preset-react',
{
development: isDevelopmentEnv || isTestEnv,
useBuiltIns: true
}
],
['@babel/preset-typescript', { allExtensions: true, isTSX: true }]
].filter(Boolean),
plugins: [
'babel-plugin-macros',
'@babel/plugin-syntax-dynamic-import',
isTestEnv && 'babel-plugin-dynamic-import-node',
'@babel/plugin-transform-destructuring',
['@babel/plugin-transform-typescript', { allowDeclareFields: true }],
[
'@babel/plugin-proposal-class-properties',
{
loose: true
}
],
[
'@babel/plugin-proposal-object-rest-spread',
{
useBuiltIns: true
}
],
[
'@babel/plugin-proposal-private-methods',
{
loose: true
}
],
[
'@babel/plugin-proposal-private-property-in-object',
{
loose: true
}
],
[
'@babel/plugin-transform-runtime',
{
helpers: false,
regenerator: true
}
],
[
'@babel/plugin-transform-regenerator',
{
async: false
}
]
].filter(Boolean)
};
};

9
bin/dev Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
if ! command -v foreman &> /dev/null
then
echo "Installing foreman..."
gem install foreman
fi
foreman start -f Procfile.dev "$@"

29
bin/vite Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# This file was generated by Bundler.
#
# The application 'vite' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require "pathname"
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
bundle_binstub = File.expand_path("../bundle", __FILE__)
if File.file?(bundle_binstub)
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
load(bundle_binstub)
else
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
end
end
require "rubygems"
require "bundler/setup"
load Gem.bin_path("vite_ruby", "vite")

View file

@ -1,18 +0,0 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"
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,18 +0,0 @@
#!/usr/bin/env ruby
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"
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

@ -133,3 +133,7 @@ SENDINBLUE_BALANCING_VALUE="50"
DOLIST_BALANCING_VALUE="50"
# Used only by a migration to choose your default regarding procedure archive dossiers after duree_conservation_dossiers_dans_ds
# DEFAULT_PROCEDURE_EXPIRES_WHEN_TERMINE_ENABLED=true
# Enable vite legacy build (IE11). Legacy build is used in production (except if set to "disabled").
# You might want to enable it in other environements for testing. Build time will be greatly impacted.
VITE_LEGACY=""

View file

@ -3,9 +3,6 @@ require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Verifies that versions and hashed value of the package contents in the project's package.json
config.webpacker.check_yarn_integrity = true
# In the development environment your application's code is reloaded any time
# it changes. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.

View file

@ -4,9 +4,6 @@ require Rails.root.join("app/lib/balancer_delivery_method")
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Verifies that versions and hashed value of the package contents in the project's package.json
config.webpacker.check_yarn_integrity = false
# Code is not reloaded between requests.
config.cache_classes = true

View file

@ -44,6 +44,10 @@ Rails.application.config.content_security_policy do |policy|
# Allow LiveReload requests
policy.connect_src(*policy.connect_src, "ws://localhost:3035", "http://localhost:3035")
# Allow Vite.js
policy.connect_src(*policy.connect_src, "ws://#{ViteRuby.config.host_with_port}")
policy.script_src(*policy.script_src, :unsafe_eval, "http://#{ViteRuby.config.host_with_port}")
# CSP are not enforced in development (see content_security_policy_report_only in development.rb)
# However we notify a random local URL, to see breakage in the DevTools when adding a new external resource.
policy.report_uri "http://#{ENV.fetch('APP_HOST')}/csp/"
@ -52,7 +56,7 @@ Rails.application.config.content_security_policy do |policy|
# Disallow all connections to external domains during tests
policy.img_src(:self, :data, :blob)
policy.script_src(:self, :unsafe_eval, :unsafe_inline, :blob)
policy.style_src(:self)
policy.style_src(:self, :unsafe_inline)
policy.connect_src(:self)
policy.frame_src(:self)
policy.default_src(:self, :data, :blob)

16
config/vite.json Normal file
View file

@ -0,0 +1,16 @@
{
"all": {
"sourceCodeDir": "app/javascript",
"watchAdditionalPaths": []
},
"development": {
"autoBuild": true,
"publicOutputDir": "vite-dev",
"port": 3036
},
"test": {
"autoBuild": true,
"publicOutputDir": "vite-test",
"port": 3037
}
}

View file

@ -1,5 +0,0 @@
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const environment = require('./environment');
module.exports = environment.toWebpackConfig();

View file

@ -1,34 +0,0 @@
const path = require('path');
const { environment } = require('@rails/webpacker');
const resolve = {
alias: {
'@utils': path.resolve(__dirname, '..', '..', 'app/javascript/shared/utils')
}
};
environment.splitChunks();
environment.config.merge({ resolve });
// Excluding node_modules From Being Transpiled By Babel-Loader
// One change to take into consideration,
// is that Webpacker 4 transpiles the node_modules folder with the babel-loader.
// This folder used to be ignored by Webpacker 3.
// The new behavior helps in case some library contains ES6 code, but in some cases it can lead to issues.
// To avoid running babel-loader in the node_modules folder, replicating the same behavior as Webpacker 3,
// we added the following code:
const nodeModulesLoader = environment.loaders.get('nodeModules');
if (!Array.isArray(nodeModulesLoader.exclude)) {
nodeModulesLoader.exclude =
nodeModulesLoader.exclude == null ? [] : [nodeModulesLoader.exclude];
}
nodeModulesLoader.exclude.push(
path.resolve(__dirname, '..', '..', 'node_modules/maplibre-gl')
);
// Uncoment next lines to run webpack-bundle-analyzer
// const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
// environment.plugins.append('BundleAnalyzer', new BundleAnalyzerPlugin());
module.exports = environment;

View file

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

View file

@ -1,5 +0,0 @@
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const environment = require('./environment');
module.exports = environment.toWebpackConfig();

View file

@ -1,95 +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: false
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
additional_paths: []
# 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:
- .tsx
- .ts
- .mjs
- .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: localhost
port: 3035
public: localhost: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

@ -1,7 +1,5 @@
{
"dependencies": {
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.16.7",
"@headlessui/react": "^1.5.0",
"@heroicons/react": "^1.0.6",
"@hotwired/stimulus": "^3.0.1",
@ -11,7 +9,6 @@
"@rails/actiontext": "^6.1.4-1",
"@rails/activestorage": "^6.1.4-1",
"@rails/ujs": "^6.1.4-1",
"@rails/webpacker": "5.4.3",
"@reach/combobox": "^0.16.5",
"@reach/slider": "^0.16.0",
"@sentry/browser": "6.12.0",
@ -19,7 +16,6 @@
"@tmcw/togeojson": "^4.3.0",
"@webcomponents/custom-elements": "^1.5.0",
"@webcomponents/template": "^1.5.0",
"babel-plugin-macros": "^2.8.0",
"chartkick": "^4.1.1",
"core-js": "^3.6.5",
"debounce": "^1.2.1",
@ -44,8 +40,6 @@
"stimulus-use": "^0.50.0",
"tiny-invariant": "^1.2.0",
"trix": "^1.2.3",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12",
"whatwg-fetch": "^3.0.0",
"yet-another-abortcontroller-polyfill": "^0.0.4",
"zod": "^3.14.4"
@ -61,24 +55,27 @@
"@types/react": "^17.0.43",
"@types/react-dom": "^17.0.14",
"@types/sortablejs": "^1.10.7",
"@typescript-eslint/eslint-plugin": "^5.8.1",
"@typescript-eslint/parser": "^5.8.1",
"babel-eslint": "^10.1.0",
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
"@vitejs/plugin-legacy": "^1.2.3",
"@vitejs/plugin-react": "^1.1.4",
"@vitejs/plugin-react-refresh": "^1.3.0",
"del-cli": "^4.0.1",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.25.1",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-react-hooks": "^4.6.0",
"netlify-cli": "^8.3.0",
"prettier": "^2.3.2",
"typescript": "^4.5.5",
"webpack-bundle-analyzer": "^3.7.0",
"webpack-dev-server": "~3"
"prettier": "^2.7.1",
"typescript": "^4.7.3",
"vite": "^2.9.1",
"vite-plugin-full-reload": "^1.0.0",
"vite-plugin-ruby": "^3.0.9"
},
"scripts": {
"clean": "del tmp public/packs public/packs-test",
"lint:js": "eslint --ext .js,.jsx,.ts,.tsx ./app/javascript ./config/webpack",
"clean": "del tmp public/packs public/packs-test public/vite public/vite-dev public/vite-test node_modules/.vite",
"lint:js": "eslint --ext .js,.jsx,.ts,.tsx ./app/javascript",
"webpack:build": "NODE_ENV=production bin/webpack",
"lint:types": "tsc",
"graphql:docs:build": "graphdoc --force",
@ -87,7 +84,7 @@
"postinstall": "patch-package"
},
"engines": {
"node": ">= 12.*"
"node": ">= 16.*"
},
"graphdoc": {
"endpoint": "https://www.demarches-simplifiees.fr/api/v2/graphql",

View file

@ -1,12 +0,0 @@
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
})
]
}

View file

@ -1,28 +1,23 @@
{
"include": ["app/javascript/**/*.ts", "app/javascript/**/*.tsx"],
"compilerOptions": {
"declaration": false,
"experimentalDecorators": true,
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": true,
"target": "ES2019",
"moduleResolution": "node",
"module": "es2020",
"jsx": "react",
"noEmit": true,
"skipLibCheck": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"types": ["react/next", "react-dom/next"],
"types": ["react/next", "react-dom/next", "vite/client"],
"paths": {
"~/*": ["./app/javascript/*"],
"@utils": ["./app/javascript/shared/utils.ts"]
}
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
},
"noEmit": true
}
}

69
vite.config.ts Normal file
View file

@ -0,0 +1,69 @@
import { defineConfig } from 'vite';
import ViteReact from '@vitejs/plugin-react';
import ViteLegacy from '@vitejs/plugin-legacy';
import FullReload from 'vite-plugin-full-reload';
import RubyPlugin from 'vite-plugin-ruby';
const plugins = [
RubyPlugin(),
ViteReact({
parserPlugins: ['classProperties', 'classPrivateProperties'],
jsxRuntime: 'classic'
}),
FullReload(['config/routes.rb', 'app/views/**/*'], { delay: 200 })
];
if (shouldBuildLegacy()) {
plugins.push(
ViteLegacy({
targets: [
'defaults',
'Chrome >= 50',
'Edge >= 14',
'Firefox >= 50',
'Opera >= 40',
'Safari >= 8',
'iOS >= 8',
'IE >= 11'
],
additionalLegacyPolyfills: [
'@stimulus/polyfills',
'@webcomponents/custom-elements',
'@webcomponents/template',
'event-target-polyfill',
'formdata-polyfill',
'intersection-observer',
'regenerator-runtime/runtime',
'whatwg-fetch',
'yet-another-abortcontroller-polyfill'
]
})
);
}
export default defineConfig({
resolve: { alias: { '@utils': '/shared/utils.ts' } },
build: {
sourcemap: true,
rollupOptions: {
output: {
manualChunks(id) {
if (id.match('maplibre') || id.match('mapbox')) {
return 'maplibre';
}
}
}
}
},
plugins
});
function shouldBuildLegacy() {
if (process.env.VITE_LEGACY == 'disabled') {
return false;
}
return (
process.env.RAILS_ENV == 'production' ||
process.env.VITE_LEGACY == 'enabled'
);
}

4915
yarn.lock

File diff suppressed because it is too large Load diff