diff --git a/.docker/apt/keys/nodesource.gpg b/.docker/apt/keys/nodesource.gpg
index 1dc1d1016b7ef..57c1c56a5c049 100644
Binary files a/.docker/apt/keys/nodesource.gpg and b/.docker/apt/keys/nodesource.gpg differ
diff --git a/.docker/apt/keys/yarn.gpg b/.docker/apt/keys/yarn.gpg
index eeb898d80297c..c08f312b8417b 100644
Binary files a/.docker/apt/keys/yarn.gpg and b/.docker/apt/keys/yarn.gpg differ
diff --git a/.docker/apt/sources.list.d/nodesource.list b/.docker/apt/sources.list.d/nodesource.list
index f58d3daf4b802..1a08cfe274525 100644
--- a/.docker/apt/sources.list.d/nodesource.list
+++ b/.docker/apt/sources.list.d/nodesource.list
@@ -1 +1 @@
-deb https://deb.nodesource.com/node_12.x buster main
+deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_24.x nodistro main
diff --git a/.docker/apt/sources.list.d/yarn.list b/.docker/apt/sources.list.d/yarn.list
index f87412037da1e..b8932f2d489c2 100644
--- a/.docker/apt/sources.list.d/yarn.list
+++ b/.docker/apt/sources.list.d/yarn.list
@@ -1 +1 @@
-deb https://dl.yarnpkg.com/debian/ stable main
+deb [signed-by=/etc/apt/keyrings/yarn.gpg] https://dl.yarnpkg.com/debian/ stable main
diff --git a/.gitignore b/.gitignore
index 48076a7c7c51f..cca8210abf16f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,6 @@
.gradle
bin
.idea
-.parcel-cache
.includepath
.ignorepath
.settings
@@ -23,10 +22,6 @@ html_docs/
vendor
air_gapped/work
-# Compiled docs.js
-.cache/
-resources/web/tests/
-
# Comes from running rspec tests
.rspec_status
diff --git a/Dockerfile b/Dockerfile
index 6414aebe3bafb..509e2f49b5633 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -23,8 +23,7 @@ RUN sed -i 's/deb.debian.org/archive.debian.org/g' /etc/apt/sources.list && \
sed -i '/buster-updates/d' /etc/apt/sources.list
RUN install_packages.sh apt-transport-https gnupg2 ca-certificates
-COPY .docker/apt/keys/nodesource.gpg /
-RUN apt-key add /nodesource.gpg
+COPY .docker/apt/keys/nodesource.gpg /etc/apt/keyrings/nodesource.gpg
COPY .docker/apt/sources.list.d/nodesource.list /etc/apt/sources.list.d/
RUN install_packages.sh \
build-essential python2 \
@@ -38,9 +37,9 @@ RUN install_packages.sh \
dumb-init
# Reap zombie git gc processes
RUN echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen && locale-gen
-ENV LANG en_US.UTF-8
-ENV LANGUAGE en_US:en
-ENV LC_ALL en_US.UTF-8
+ENV LANG=en_US.UTF-8
+ENV LANGUAGE=en_US:en
+ENV LC_ALL=en_US.UTF-8
FROM base AS ruby_deps
@@ -59,8 +58,7 @@ RUN cd /var/lib/gems/2.5.0/gems/asciidoctor-2.0.10 && patch -p1 < /asciidoctor_2
FROM base AS node_deps
-COPY .docker/apt/keys/yarn.gpg /
-RUN apt-key add /yarn.gpg
+COPY .docker/apt/keys/yarn.gpg /etc/apt/keyrings/yarn.gpg
COPY .docker/apt/sources.list.d/yarn.list /etc/apt/sources.list.d/
RUN install_packages.sh yarn=1.22.19-1
COPY package.json /
diff --git a/build_docs b/build_docs
index 505f7dac9dc1c..243cc800c60d1 100755
--- a/build_docs
+++ b/build_docs
@@ -81,18 +81,19 @@ def build_docker_image(name):
class OpenBrowserState:
def __init__(self):
self.need_nginx = True
- self.need_parcel = False
+ self.need_web_resources = False
self.need_preview = False
self.opened = False
def building_single_book(self):
"""
- If we're building a single book we need to wait for Parcel to finish
- building the CSS and JS for the first time so we can be sure its server
- is up and running. If we're building all books we run parcel as part
- of the build before starting nginx so we don't have to wait for it.
+ If we're building a single book we need to wait for Vite to finish
+ building the CSS and JS for the first time so we can be sure nginx
+ has something to serve. If we're building all books we run vite as
+ part of the build before starting nginx so we don't have to wait for
+ it.
"""
- self.need_parcel = True
+ self.need_web_resources = True
self.need_preview = True
def handle_line(self, line):
@@ -102,16 +103,16 @@ class OpenBrowserState:
if 'start worker processes' in line:
# Wait for nginx or nothing will be listening
self.need_nginx = False
- if '✨ Built in ' in line:
- # Wait for parcel to finish building for the first time or the
- # server might not yet be up and nginx will fail to proxy to it.
- self.need_parcel = False
+ if 'built in ' in line:
+ # Wait for vite to finish building for the first time or there
+ # won't be any css or js for nginx to serve yet.
+ self.need_web_resources = False
show = False
if 'preview server is listening on 3000' in line:
self.need_preview = False
show = False
if not self.need_nginx and \
- not self.need_parcel and \
+ not self.need_web_resources and \
not self.need_preview:
if platform == "darwin" and 'BROWSER' not in environ:
# On mac webbrowser seeem to want to default to safari which
@@ -265,7 +266,6 @@ def run_build_docs(args):
saw_doc = True
elif arg == '--open':
docker_args.extend(['--publish', '8000:8000/tcp'])
- docker_args.extend(['--publish', '8001:8001/tcp'])
open_browser = OpenBrowserState()
elif arg == '--out':
out_dir = realpath(args.next_arg_or_err())
@@ -325,11 +325,11 @@ def run_build_docs(args):
if platform == "darwin" and saw_doc and open_browser:
# Docker for Mac has trouble watching filesystem events on a mounted
- # volume, so Parcel's watcher was not triggering rebuilds. Using
+ # volume, so Vite's watcher was not triggering rebuilds. Using
# polling is more expensive and requires a higher ulimit, but
# resolves the issue. See:
# - https://github.com/docker/for-mac/issues/2216
- # - https://github.com/parcel-bundler/parcel/issues/2539
+ # (vite.config.mjs turns CHOKIDAR_USEPOLLING into polling.)
docker_args.extend([
"-e", "CHOKIDAR_USEPOLLING=1",
"--ulimit", "nofile=90000:90000"
@@ -347,7 +347,7 @@ def run_build_docs(args):
def handle_line(line):
show = True
- if 'Server running at http://localhost:1234' in line:
+ if 'watching for file changes' in line:
show = False
if open_browser:
show = show and open_browser.handle_line(line)
diff --git a/build_docs.pl b/build_docs.pl
index a972cd9b06537..4e15a19291b66 100755
--- a/build_docs.pl
+++ b/build_docs.pl
@@ -995,7 +995,7 @@ sub serve_local_preview {
wait;
}
if ( $web_resources_pid ) {
- say 'Terminating preview services...parcel';
+ say 'Terminating preview services...web resources';
kill 'TERM', $web_resources_pid;
wait;
}
diff --git a/integtest/spec/all_books_spec.rb b/integtest/spec/all_books_spec.rb
index 2ca0c81f95fd3..342093aaada6b 100644
--- a/integtest/spec/all_books_spec.rb
+++ b/integtest/spec/all_books_spec.rb
@@ -52,7 +52,6 @@ def self.has_license(name, heading)
has_license 'code-prettify', 'The Apache 2.0 License'
has_license "code-prettify's lang-sql", 'The Apache 2.0 License'
has_license "code-prettify's lang-yaml", 'The Apache 2.0 License'
- has_license 'details-polyfill', 'The MIT License (MIT)'
has_license 'js-cookie', 'The MIT License (MIT)'
has_license 'linkstate', 'The MIT License (MIT)'
has_license 'loose-envify', 'The MIT License (MIT)'
@@ -70,9 +69,9 @@ def self.has_license(name, heading)
has_license 'Noto Sans Japanese', 'SIL OPEN FONT LICENSE'
has_license 'Roboto Mono', 'APACHE LICENSE'
end
- file_context 'html/static/Inter-Medium.5d08e0ba.woff2'
- file_context 'html/static/NotoSansJP-Black.df80409c.woff2'
- file_context 'html/static/roboto-mono-latin-400-normal.b1632429.woff2'
+ file_context 'html/static/Inter-Medium.woff2'
+ file_context 'html/static/NotoSansJP-Black.woff2'
+ file_context 'html/static/roboto-mono-latin-400-normal.woff2'
file_context 'html/sitemap.xml' do
it 'has an entry for the chapter' do
expect(contents).to include(<<~XML)
diff --git a/integtest/spec/helper/dsl/convert_all.rb b/integtest/spec/helper/dsl/convert_all.rb
index 3d4cf9759dded..0bf9fe692bce6 100644
--- a/integtest/spec/helper/dsl/convert_all.rb
+++ b/integtest/spec/helper/dsl/convert_all.rb
@@ -72,7 +72,7 @@ def convert_all_before_context(relative_conf: false, target_branch: nil,
file_context 'html/static/docs-v1.js' do
it 'is minified' do
expect(contents).to include(<<~JS.strip)
- return a&&a.__esModule?{d:a.default}:{d:a}
+ (function(){var e=Object.create
JS
end
it "doesn't include a source map" do
diff --git a/integtest/spec/helper/opened_docs.rb b/integtest/spec/helper/opened_docs.rb
index 788a51dd3093e..8911c3894fad7 100644
--- a/integtest/spec/helper/opened_docs.rb
+++ b/integtest/spec/helper/opened_docs.rb
@@ -16,6 +16,6 @@ def initialize(cmd, uses_preview)
return unless uses_preview
wait_for_logs(/^preview server is listening on 3000$/, 60)
- wait_for_logs(/ Built in /, 60) # Wait for parcel as well
+ wait_for_logs(/built in /, 60) # Wait for vite as well
end
end
diff --git a/integtest/spec/single_book_spec.rb b/integtest/spec/single_book_spec.rb
index 0b250fabe8129..c034b2a94362d 100644
--- a/integtest/spec/single_book_spec.rb
+++ b/integtest/spec/single_book_spec.rb
@@ -769,13 +769,10 @@ def self.convert_with_source_branch_before_context(branch)
context 'the js' do
it 'is unminified' do
- expect(js).to serve(include(<<~JS))
- // Test comment used to detect unminifed JS in tests
- JS
- end
- it 'include hot module replacement for the css' do
- expect(js).to serve(include(<<~JS))
- // Setup hot module replacement for css if we're in dev mode.
+ # Vite drops plain comments from unminified output so look for a
+ # function name instead.
+ expect(js).to serve(include(<<~JS.strip))
+ function init_landing_page()
JS
end
it 'includes a source map' do
@@ -800,9 +797,6 @@ def self.convert_with_source_branch_before_context(branch)
/* test comment used to detect unminified source */
CSS
end
- it 'includes a source map' do
- expect(css).to serve(include('sourceMappingURL='))
- end
end
end
diff --git a/jest.js b/jest.js
deleted file mode 100644
index 9d35ec5944b02..0000000000000
--- a/jest.js
+++ /dev/null
@@ -1,2 +0,0 @@
-var jQuery = require("jquery");
-window.$ = window.jQuery = jQuery;
diff --git a/lib/ES/Util.pm b/lib/ES/Util.pm
index dfc86f405f563..dc897b6a2b5e0 100644
--- a/lib/ES/Util.pm
+++ b/lib/ES/Util.pm
@@ -496,7 +496,6 @@ sub write_nginx_test_config {
my $web_conf;
if ( $watching_web ) {
$web_conf = <<"CONF"
- rewrite ^/guide/static/docs-v1\\.js(.*)\$ /guide/static/docs_js/index-v1.js\$1 last;
location ^~ /guide/static/jquery.js {
alias /node_modules/jquery/dist/jquery.js;
types {
@@ -504,7 +503,8 @@ sub write_nginx_test_config {
}
}
location ^~ /guide/static/ {
- proxy_pass http://0.0.0.0:1234;
+ alias /tmp/web_resources_watch/;
+ add_header Cache-Control 'no-cache';
}
CONF
} else {
@@ -689,16 +689,17 @@ sub timestamp {
#===================================
sub start_web_resources_watcher {
#===================================
- my $parcel_pid = fork;
- return $parcel_pid if $parcel_pid;
+ my $vite_pid = fork;
+ return $vite_pid if $vite_pid;
close STDIN;
open( STDIN, "file('docs_js/index-v1.js');
- my $compiled_css = $parcel_out->file('styles-v1.css');
+ my $vite_out = dir('/tmp/web_resources');
+ my $compiled_js = $vite_out->file('docs-v1.js');
+ my $compiled_css = $vite_out->file('styles-v1.css');
unless ( -e $compiled_js && -e $compiled_css ) {
# We write the compiled js and css to /tmp so we can use them on
@@ -734,13 +735,12 @@ sub build_web_resources {
# when you run the integration tests and saves about 1.5 seconds on
# every docs build.
say "Compiling web resources";
- run '/node_modules/parcel/bin/cli.js', 'build',
- '--public-url', '/guide/static/',
- '--experimental-scope-hoisting', '--no-source-maps',
- '-d', $parcel_out,
- 'resources/web/docs_js/index-v1.js', 'resources/web/styles-v1.pcss';
- die "Parcel didn't make $compiled_js" unless -e $compiled_js;
- die "Parcel didn't make $compiled_css" unless -e $compiled_css;
+ run '/node_modules/vite/bin/vite.js', 'build',
+ '--configLoader', 'native',
+ '--config', 'resources/web/vite.config.mjs',
+ '--outDir', $vite_out;
+ die "Vite didn't make $compiled_js" unless -e $compiled_js;
+ die "Vite didn't make $compiled_css" unless -e $compiled_css;
}
my $static_dir = $dest->subdir( 'raw' )->subdir( 'static' );
@@ -758,8 +758,9 @@ sub build_web_resources {
$css_licenses->slurp( iomode => '<:encoding(UTF-8)' ) . $compiled_css->slurp( iomode => '<:encoding(UTF-8)' )
);
- for ( $parcel_out->children ) {
- next unless /.+\.woff2?/;
+ # The fonts that the css refers to.
+ for ( $vite_out->children ) {
+ next if $_->basename eq 'docs-v1.js' || $_->basename eq 'styles-v1.css';
rcopy( $_, $static_dir );
}
diff --git a/package.json b/package.json
index fd671636add28..a856b9a5bfa18 100644
--- a/package.json
+++ b/package.json
@@ -2,24 +2,20 @@
"license": "SEE LICENSE IN README.asciidoc",
"devDependencies": {
"jest": "^24.8.0",
- "nock": "^10.0.6",
- "rmfr": "^2.0.0"
+ "jsdom": "^30.1.3",
+ "nock": "^13.5.6",
+ "rmfr": "^2.0.0",
+ "vitest": "^5.0.5"
},
"scripts": {
- "test": "jest"
- },
- "jest": {
- "setupFiles": [
- "./jest.js"
- ]
+ "test": "vitest run --root resources/web",
+ "test:preview": "jest preview/__test__"
},
"dependencies": {
"dedent": "^0.7.0",
- "details-polyfill": "^1.1.0",
"jquery": "3.5.1",
"js-cookie": "^2.1.0",
"linkstate": "^1.1.1",
- "parcel": "^1.12.3",
"postcss-assets": "^5.0.0",
"preact": "^8.4.2",
"preact-context": "^1.1.3",
@@ -29,7 +25,10 @@
"recursive-copy": "^2.0.10",
"redux": "^4.0.4",
"redux-thunk": "^2.3.0",
- "url-search-params-polyfill": "^8.0.0",
+ "vite": "^8.3.5",
"yargs": "^14.0.0"
+ },
+ "engines": {
+ "node": ">=22.12.0"
}
}
diff --git a/preview/__test__/clean.test.js b/preview/__test__/clean.test.js
index 7017b4e45c98c..f9c9eddd96cd2 100644
--- a/preview/__test__/clean.test.js
+++ b/preview/__test__/clean.test.js
@@ -105,7 +105,7 @@ describe('Cleaner.is_pr_closed', () => {
test('complains if github returns invalid json', async () => {
mock_github().reply(200, 'pure garbage');
await expect(cleaner.is_pr_closed({repo: 'r', number: 1})).rejects
- .toThrow(/Unexpected token p/);
+ .toThrow(/Unexpected token/);
});
test('complains if github returns unexpect json', async () => {
mock_github().reply(200, JSON.stringify({
@@ -114,7 +114,7 @@ describe('Cleaner.is_pr_closed', () => {
}
}));
await expect(cleaner.is_pr_closed({repo: 'r', number: 1})).rejects
- .toThrow(/Cannot read property 'closed' of undefined/);
+ .toThrow(/Cannot read propert(y|ies) of undefined/);
});
test("backs off if there aren't many requests remaining", async () => {
// Mock setTimeout to immediately run. We don't use jest.useFakeTimers
diff --git a/resources/web/Makefile b/resources/web/Makefile
index 54067d13f3f48..3fcdb3966c77d 100644
--- a/resources/web/Makefile
+++ b/resources/web/Makefile
@@ -1,13 +1,8 @@
include ../../common.mk
.PHONY: check
-check: jest
+check: test
-.PHONY: jest
-jest: tests
- $(DOCKER) node_test /node_modules/jest/bin/jest.js ./tests/** ./__test__/**
-
-.PHONY: tests
-tests:
- rm -rf tests
- $(DOCKER) node_test /node_modules/parcel/bin/cli.js build ./docs_js/__tests__/**/* ./docs_js/__tests__/* -d ./tests/ --target node --no-minify --no-source-maps
+.PHONY: test
+test:
+ $(DOCKER) node_test /node_modules/vitest/vitest.mjs run
diff --git a/resources/web/__test__/air_gapped_template.test.js b/resources/web/__test__/air_gapped_template.test.js
index 5cac7ab6aca9a..0ba5f73ddff99 100644
--- a/resources/web/__test__/air_gapped_template.test.js
+++ b/resources/web/__test__/air_gapped_template.test.js
@@ -1,3 +1,4 @@
+// @vitest-environment node
/**
* @license
* Licensed to Elasticsearch under one or more contributor
diff --git a/resources/web/docs.js.licenses b/resources/web/docs.js.licenses
index 185f421b068d4..dd5a12557671f 100644
--- a/resources/web/docs.js.licenses
+++ b/resources/web/docs.js.licenses
@@ -51,29 +51,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. */
-/* details-polyfill
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Rico Sta. Cruz
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
/* js-cookie
* The MIT License (MIT)
*
diff --git a/resources/web/docs_js/__tests__/actions/settings.test.js b/resources/web/docs_js/__tests__/actions/settings.test.js
index 09f958d7436b0..e1e01c650643d 100644
--- a/resources/web/docs_js/__tests__/actions/settings.test.js
+++ b/resources/web/docs_js/__tests__/actions/settings.test.js
@@ -1,4 +1,4 @@
-import Cookies from "../../../../../../node_modules/js-cookie";
+import Cookies from "js-cookie";
import * as actions from "../../actions/settings";
import store from "../../store";
@@ -10,7 +10,7 @@ describe("saveSettings", () => {
});
test("it converts a map to list of tuples", () => {
- const setCookies = jest.fn();
+ const setCookies = vi.fn();
const saveSettings = actions._saveSettings(setCookies);
db.dispatch(saveSettings({
console_url: "c",
diff --git a/resources/web/docs_js/__tests__/components/alternative_picker.test.jsx b/resources/web/docs_js/__tests__/components/alternative_picker.test.jsx
index c524bb838ae67..81e5581a9ca90 100644
--- a/resources/web/docs_js/__tests__/components/alternative_picker.test.jsx
+++ b/resources/web/docs_js/__tests__/components/alternative_picker.test.jsx
@@ -1,4 +1,4 @@
-import {h, render} from "../../../../../../node_modules/preact";
+import {h, render} from "preact";
import {_AlternativePicker} from "../../components/alternative_picker";
describe(_AlternativePicker, () => {
diff --git a/resources/web/docs_js/__tests__/components/mount.test.js b/resources/web/docs_js/__tests__/components/mount.test.jsx
similarity index 82%
rename from resources/web/docs_js/__tests__/components/mount.test.js
rename to resources/web/docs_js/__tests__/components/mount.test.jsx
index 6cbc4bfce5978..9c882663e9f00 100644
--- a/resources/web/docs_js/__tests__/components/mount.test.js
+++ b/resources/web/docs_js/__tests__/components/mount.test.jsx
@@ -1,5 +1,5 @@
-import {h} from "../../../../../../node_modules/preact";
-import {connect} from "../../../../../../node_modules/preact-redux";
+import {h} from "preact";
+import {connect} from "preact-redux";
import {newStore} from "../../store";
import {mount} from "../../components/mount";
diff --git a/resources/web/docs_js/__tests__/docs.test.js b/resources/web/docs_js/__tests__/docs.test.js
index 80bd11bf55484..f6666bfc59243 100644
--- a/resources/web/docs_js/__tests__/docs.test.js
+++ b/resources/web/docs_js/__tests__/docs.test.js
@@ -1,5 +1,5 @@
import {jQuery} from "../deps";
-import dedent from "../../../../../node_modules/dedent";
+import dedent from "dedent";
import {init_console_widgets, init_headers} from "../index-v1";
import * as utils from "../utils";
import * as l from "../localization";
@@ -41,7 +41,7 @@ function pageWithConsole(name, consoleText, extraTextAssertions) {
});
describe('when clicked', () => {
beforeEach(() => {
- document.execCommand = jest.fn(() => {
+ document.execCommand = vi.fn(() => {
document.copied = jQuery('textarea').val();
return true;
});
diff --git a/resources/web/docs_js/__tests__/localization.test.js b/resources/web/docs_js/__tests__/localization.test.js
index 41b029648e9e9..78093f9e5bb2a 100644
--- a/resources/web/docs_js/__tests__/localization.test.js
+++ b/resources/web/docs_js/__tests__/localization.test.js
@@ -1,10 +1,11 @@
import * as l from "../localization";
-import * as R from "../../../../../node_modules/ramda";
+import toPairs from "ramda/src/toPairs";
+import forEach from "ramda/src/forEach";
describe("Localization of strings", () => {
- const specs = R.toPairs(l.lang_spec);
+ const specs = toPairs(l.lang_spec);
- R.forEach(([phrase, {zh_cn, en}]) => {
+ forEach(([phrase, {zh_cn, en}]) => {
const expectedEn = en ? en : phrase;
test(`Correct Chinese translation of the phrase ${phrase}`, () => {
diff --git a/resources/web/docs_js/__tests__/prettify/lang-asciidoc.test.js b/resources/web/docs_js/__tests__/prettify/lang-asciidoc.test.js
index c94dc2c63d548..f974d6a59c3c2 100644
--- a/resources/web/docs_js/__tests__/prettify/lang-asciidoc.test.js
+++ b/resources/web/docs_js/__tests__/prettify/lang-asciidoc.test.js
@@ -1,6 +1,6 @@
import PR from "../../../lib/prettify/prettify";
import "../../prettify/lang-asciidoc";
-import dedent from "../../../../../../node_modules/dedent";
+import dedent from "dedent";
const prettyAsciidoc = str => PR.prettyPrintOne(str, "asciidoc");
const tag = str => `${str}`;
diff --git a/resources/web/docs_js/__tests__/prettify/lang-console.test.js b/resources/web/docs_js/__tests__/prettify/lang-console.test.js
index afd8c7b399b4e..4115cbab0d879 100644
--- a/resources/web/docs_js/__tests__/prettify/lang-console.test.js
+++ b/resources/web/docs_js/__tests__/prettify/lang-console.test.js
@@ -1,6 +1,6 @@
import PR from "../../../lib/prettify/prettify";
import "../../prettify/lang-console";
-import dedent from "../../../../../../node_modules/dedent";
+import dedent from "dedent";
const prettyConsole = str => PR.prettyPrintOne(str, "console");
const prettyJs = str => PR.prettyPrintOne(str, "js");
diff --git a/resources/web/docs_js/actions/index.js b/resources/web/docs_js/actions/index.js
index b7bb49757311a..cf2657bce073e 100644
--- a/resources/web/docs_js/actions/index.js
+++ b/resources/web/docs_js/actions/index.js
@@ -1,4 +1,4 @@
-import {combineReducers} from "../../../../../node_modules/redux";
+import {combineReducers} from "redux";
import {reducer as settingsReducer} from "./settings";
import {reducer as modalReducer} from "./modal";
diff --git a/resources/web/docs_js/actions/modal.js b/resources/web/docs_js/actions/modal.js
index 4439da4e99c34..68fca8ae0c00d 100644
--- a/resources/web/docs_js/actions/modal.js
+++ b/resources/web/docs_js/actions/modal.js
@@ -1,4 +1,4 @@
-import {dissoc} from "../../../../../node_modules/ramda";
+import dissoc from "ramda/src/dissoc";
const initialState = {isOpen: false, Component: null, props: null};
diff --git a/resources/web/docs_js/actions/settings.js b/resources/web/docs_js/actions/settings.js
index 6618f359a0507..2634435832d89 100644
--- a/resources/web/docs_js/actions/settings.js
+++ b/resources/web/docs_js/actions/settings.js
@@ -1,5 +1,8 @@
-import Cookies from "../../../../../node_modules/js-cookie";
-import {omit, merge, toPairs, forEach} from "../../../../../node_modules/ramda";
+import Cookies from "js-cookie";
+import omit from "ramda/src/omit";
+import merge from "ramda/src/merge";
+import toPairs from "ramda/src/toPairs";
+import forEach from "ramda/src/forEach";
import {closeModal} from "./modal";
const SAVE_SETTING = "SAVE_SETTING";
diff --git a/resources/web/docs_js/components/alternative_picker.jsx b/resources/web/docs_js/components/alternative_picker.jsx
index 6c20155149ef1..ddbef00844851 100644
--- a/resources/web/docs_js/components/alternative_picker.jsx
+++ b/resources/web/docs_js/components/alternative_picker.jsx
@@ -3,9 +3,10 @@
* instead of "Console".
*/
-import {h, Component} from "../../../../../../node_modules/preact";
-import {pick, merge} from "../../../../../node_modules/ramda";
-import {connect} from "../../../../../node_modules/preact-redux";
+import {h, Component} from "preact";
+import pick from "ramda/src/pick";
+import merge from "ramda/src/merge";
+import {connect} from "preact-redux";
import {saveSettings} from "../actions/settings";
const alternativePrettyName = rawName => {
diff --git a/resources/web/docs_js/components/alternative_switcher.js b/resources/web/docs_js/components/alternative_switcher.js
index 24c056dbfd06e..f3e869745007c 100644
--- a/resources/web/docs_js/components/alternative_switcher.js
+++ b/resources/web/docs_js/components/alternative_switcher.js
@@ -1,4 +1,4 @@
-import {curry} from "../../../../../node_modules/ramda";
+import curry from "ramda/src/curry";
/*
* Widget to switch the displayed alternative langauge when the configured
diff --git a/resources/web/docs_js/components/console_widget.jsx b/resources/web/docs_js/components/console_widget.jsx
index 7b11aa1e2d069..7939c5e9865d4 100644
--- a/resources/web/docs_js/components/console_widget.jsx
+++ b/resources/web/docs_js/components/console_widget.jsx
@@ -1,8 +1,11 @@
import * as utils from "../utils";
-import {prop, pick, merge, omit} from "../../../../../node_modules/ramda";
-import {h, Component} from "../../../../../node_modules/preact";
-import linkState from "../../../../../node_modules/linkstate";
-import {connect} from "../../../../../node_modules/preact-redux";
+import prop from "ramda/src/prop";
+import pick from "ramda/src/pick";
+import merge from "ramda/src/merge";
+import omit from "ramda/src/omit";
+import {h, Component} from "preact";
+import linkState from "linkstate";
+import {connect} from "preact-redux";
import {openModal} from "../actions/modal";
import {saveSettings} from "../actions/settings";
import AlternativePicker from "./alternative_picker";
diff --git a/resources/web/docs_js/components/feedback_modal.jsx b/resources/web/docs_js/components/feedback_modal.jsx
index c47e88699a469..26ef16733e12c 100644
--- a/resources/web/docs_js/components/feedback_modal.jsx
+++ b/resources/web/docs_js/components/feedback_modal.jsx
@@ -1,4 +1,4 @@
-import { h, Component } from '../../../../../../node_modules/preact';
+import { h, Component } from 'preact';
const FEEDBACK_URL = 'https://docs.elastic.co/api/feedback'
const MAX_COMMENT_LENGTH = 1000;
diff --git a/resources/web/docs_js/components/feedback_widget.jsx b/resources/web/docs_js/components/feedback_widget.jsx
index a8a3a0bc67de0..36038b1b86978 100644
--- a/resources/web/docs_js/components/feedback_widget.jsx
+++ b/resources/web/docs_js/components/feedback_widget.jsx
@@ -1,4 +1,4 @@
-import { h, Component } from '../../../../../../node_modules/preact';
+import { h, Component } from 'preact';
export default class FeedbackWidget extends Component {
render() {
diff --git a/resources/web/docs_js/components/modal.js b/resources/web/docs_js/components/modal.jsx
similarity index 77%
rename from resources/web/docs_js/components/modal.js
rename to resources/web/docs_js/components/modal.jsx
index e0dc5ca1dad1a..477ade62aca87 100644
--- a/resources/web/docs_js/components/modal.js
+++ b/resources/web/docs_js/components/modal.jsx
@@ -1,5 +1,5 @@
-import {h} from "../../../../../node_modules/preact";
-import {connect} from "../../../../../node_modules/preact-redux";
+import {h} from "preact";
+import {connect} from "preact-redux";
import {closeModal} from "../actions/modal";
export const Modal = ({Component, props, isOpen, closeModal}) => {
diff --git a/resources/web/docs_js/components/mount.js b/resources/web/docs_js/components/mount.jsx
similarity index 69%
rename from resources/web/docs_js/components/mount.js
rename to resources/web/docs_js/components/mount.jsx
index 30ea27458e6ae..267f011eb0a92 100644
--- a/resources/web/docs_js/components/mount.js
+++ b/resources/web/docs_js/components/mount.jsx
@@ -1,5 +1,5 @@
-import { Provider } from '../../../../../node_modules/preact-redux';
-import { h, render } from '../../../../../node_modules/preact';
+import { Provider } from 'preact-redux';
+import { h, render } from 'preact';
import store from "../store";
export const mount = ({el, Component, props = {}, store}) =>
diff --git a/resources/web/docs_js/deps.js b/resources/web/docs_js/deps.js
index 7c06279a68a5c..cee08a98ac714 100644
--- a/resources/web/docs_js/deps.js
+++ b/resources/web/docs_js/deps.js
@@ -1,4 +1,4 @@
-import _Cookies from "../../../../node_modules/js-cookie";
+import _Cookies from "js-cookie";
export const jQuery = window.jQuery;
export const $ = window.jQuery;
diff --git a/resources/web/docs_js/index-v1.js b/resources/web/docs_js/index-v1.js
index b8d6f31a988fc..fa4228303c28f 100644
--- a/resources/web/docs_js/index-v1.js
+++ b/resources/web/docs_js/index-v1.js
@@ -2,8 +2,8 @@ import AlternativeSwitcher from "./components/alternative_switcher.js";
import ConsoleWidget from "./components/console_widget.jsx";
import FeedbackModal from './components/feedback_modal.jsx';
import FeedbackWidget from './components/feedback_widget.jsx';
-import Modal from "./components/modal.js";
-import mount from "./components/mount.js";
+import Modal from "./components/modal.jsx";
+import mount from "./components/mount.jsx";
import {switchTabs} from "./components/tabbed_widget.js";
import {Cookies, $} from "./deps.js";
import {lang_strings} from "./localization.js";
@@ -16,11 +16,8 @@ import "../lib/prettify/lang-esql.js";
import "../lib/prettify/lang-sql.js";
import "../lib/prettify/lang-yaml.js";
-// Add support for in IE and the like
-import "../../../../../node_modules/details-polyfill";
-
-// Add support for URLSearchParams Web API in IE
-import "../../../../../node_modules/url-search-params-polyfill";
+// Vite emits the CSS as styles-v1.css next to the built script
+import "../styles-v1.pcss";
export function init_landing_page() {
// Because of the nature of the injected links, we need to adjust the layout to
@@ -571,8 +568,6 @@ $(function() {
...getUtm()
};
dataLayer.push(pageViewData);
-
- // Test comment used to detect unminifed JS in tests
});
// Tabbed widgets
diff --git a/resources/web/docs_js/prettify/lang-console.js b/resources/web/docs_js/prettify/lang-console.js
index f84728cc64ec5..a90c6882cc6c0 100644
--- a/resources/web/docs_js/prettify/lang-console.js
+++ b/resources/web/docs_js/prettify/lang-console.js
@@ -20,12 +20,13 @@
import PR from "../../lib/prettify/prettify";
+// Note: PR drops regex flags so `[\s\S]` stands in for the `s` flag.
const basic = PR.createSimpleLexer(
[
[PR.PR_PUNCTUATION, /^[/?=&]/, null, '/?=&'],
[PR.PR_PLAIN, /^\s+/, null, ' \t\r\n'],
[PR.PR_KEYWORD, /^DELETE|HEAD|GET|PATCH|POST|PUT/, null, 'DHGP'],
- ["lang-js", /^(\{.+?\})(?=\s*(DELETE|HEAD|GET|PATCH|POST|PUT|$))/s, null, '{'],
+ ["lang-js", /^(\{[\s\S]+?\})(?=\s*(DELETE|HEAD|GET|PATCH|POST|PUT|$))/, null, '{'],
],
[
[PR.PR_STRING, /^[^ \s/?=&]+/],
diff --git a/resources/web/docs_js/store.js b/resources/web/docs_js/store.js
index 11d0cca64ff37..4f7300ebe2598 100644
--- a/resources/web/docs_js/store.js
+++ b/resources/web/docs_js/store.js
@@ -1,5 +1,5 @@
-import thunk from '../../../../node_modules/redux-thunk';
-import { createStore, applyMiddleware } from '../../../../node_modules/redux';
+import thunk from 'redux-thunk';
+import { createStore, applyMiddleware } from 'redux';
import reducer from "./actions";
export const newStore = initialState =>
diff --git a/resources/web/postcss.config.js b/resources/web/postcss.config.js
index 69362ff101a4f..c2d0a30261f00 100644
--- a/resources/web/postcss.config.js
+++ b/resources/web/postcss.config.js
@@ -1,6 +1,12 @@
+const path = require('path');
+
module.exports = {
plugins: [
require('precss')(),
- require('postcss-assets'),
+ require('postcss-assets')({
+ // `inline("img/foo.svg")` is relative to the style directory.
+ basePath: __dirname,
+ loadPaths: ['style/'],
+ }),
],
};
diff --git a/resources/web/vite.config.mjs b/resources/web/vite.config.mjs
new file mode 100644
index 0000000000000..e10998d6a41e3
--- /dev/null
+++ b/resources/web/vite.config.mjs
@@ -0,0 +1,59 @@
+import { defineConfig } from 'vite';
+
+// Builds the docs' browser resources. `index-v1.js` is the only entry point
+// and it imports `styles-v1.pcss`, so one build makes both files:
+//
+// docs-v1.js a classic (IIFE) script, loaded with a plain