Repository navigation
Build the backend assets with webpack instead of gulp - #461
Conversation
Move the backend Sass build and the vendor copies (jQuery, Bootstrap 3 JS, datepicker, tagsinput, cropper, fine-uploader, Font Awesome 4 fonts and CKEditor) from gulpfile.js into webpack.backend.js, exported next to the theme config from webpack.dev.js and webpack.prod.js. The frontend core, Search, Fork theme and photoswipe tasks are dropped: nothing active builds from them and their output stays committed. The CKEditor copy skips codemirror and lineutils (not in the npm package) and strips the UTF-8 BOM the npm files ship with, so the committed copies stay unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Switch the theme sass-loader to the modern Sass API and silence deprecation warnings coming from node_modules (bootstrap5). - Drop the empty screen.js and editor_content.js stubs the theme build emitted for its Sass-only entries. - Write the BOM in the CKEditor copy transform as an escape instead of a literal invisible character. - Use StandardJS style in webpack.dev.js and webpack.prod.js. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideConsolidates backend and theme asset compilation under webpack by introducing a dedicated backend compiler, migrating required vendor and CKEditor outputs while preserving committed-file compatibility, removing the Gulp toolchain and obsolete assets, and updating CI, deployment, and documentation to run the unified build. Sequence diagram for unified asset build in CIsequenceDiagram
participant CI
participant NPM as npm run build
participant Webpack
participant ThemeCompiler
participant BackendCompiler
participant Assets as Committed asset outputs
CI->>NPM: npm run build
NPM->>Webpack: Run webpack.prod.js
Webpack->>ThemeCompiler: Build theme assets
Webpack->>BackendCompiler: Build backend assets
BackendCompiler->>Assets: Compile backend Sass
BackendCompiler->>Assets: Copy vendor files
BackendCompiler->>Assets: Copy CKEditor files
ThemeCompiler->>Assets: Write theme assets
Flow diagram for backend asset migration from Gulp to Webpackflowchart LR
Gulp[Gulp backend pipeline]
BackendConfig[webpack.backend.js]
Sass[Backend Sass]
Vendors[Vendor and CKEditor files]
CSS[Backend CSS outputs]
JS[Backend vendor and CKEditor outputs]
Gulp -. removed .-> BackendConfig
BackendConfig --> Sass
BackendConfig --> Vendors
Sass --> CSS
Vendors --> JS
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 6 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="package.json" line_range="35" />
<code_context>
"css-loader": "^6.8.1",
"fine-uploader": "^5.14.1",
"font-awesome": "^4.7.0",
- "gulp": "^4.0.2",
- "gulp-autoprefixer": "^8.0.0",
- "gulp-livereload": "^4.0.1",
</code_context>
<issue_to_address>
**Deployment asset builds stop**
When a deployment reaches `fork:theme:build` with dependencies installed from the new lockfile, `fork:theme:build` runs `node_modules/.bin/gulp build` before `npm run build`, but Gulp was removed from the dependencies and the gulpfile was deleted, so the command exits nonzero and the webpack build and asset upload do not run.
Update `fork:theme:build` to run the asset build without Gulp, or restore the Gulp dependency and gulpfile.
</issue_to_address>
### Comment 2
<location path="webpack.backend.js" line_range="1" />
<code_context>
+const path = require('path')
+const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts')
</code_context>
<issue_to_address>
**Backend build config is exposed**
When a deployment uses the `clear_paths` list and serves the release through the repository’s `.htaccess` rules, `deploy.php` does not remove `webpack.backend.js` as it does the other webpack configs, and `.htaccess` does not block it; Apache serves the deployed file directly, exposing the backend asset build configuration to visitors.
Add `webpack.backend.js` to `deploy.php`’s `clear_paths` and explicitly block it in `.htaccess` for deployments that do not use that list.
</issue_to_address>
### Comment 3
<location path="webpack.backend.js" line_range="90-100" />
<code_context>
+ 'font-awesome/fonts/*'
+ ], 'fonts/vendors'),
+ ...copyVendorFiles([
+ 'jquery/dist/jquery.min.js',
+ 'jquery-migrate/dist/jquery-migrate.min.js',
+ 'jquery-ui-dist/jquery-ui.min.js',
+ 'bootstrap-sass/assets/javascripts/bootstrap.min.js',
+ 'bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js',
+ 'fine-uploader/jquery.fine-uploader/jquery.fine-uploader.min.js',
+ 'simple-ajax-uploader/SimpleAjaxUploader.min.js',
+ 'bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js',
+ 'cropper/dist/cropper.js',
+ 'bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.min.js'
+ ], 'js/vendors'),
+ ...ckeditorFiles.map((file) => ({
+ from: file,
</code_context>
<issue_to_address>
**Autocomplete scripts are missing**
When the committed typeahead asset is absent or removed, or the unified webpack build is used to produce assets, the vendor copy list omits `typeahead.bundle.min.js` while `Header::addCoreJs()` and frontend Search still request it, so backend typeahead widgets and frontend autocomplete load a missing script and stop working.
Add `typeahead.bundle.min.js` to the webpack vendor copy list.
</issue_to_address>
### Comment 4
<location path="webpack.backend.js" line_range="9" />
<code_context>
+// copies node_modules files flat into a folder in the project root, untouched by the minimizer
+const copyVendorFiles = (files, folder) => files.map((file) => ({
+ from: `node_modules/${file}`,
+ to: path.resolve(__dirname, folder, '[name][ext]'),
+ info: { minimized: true }
+}))
</code_context>
<issue_to_address>
**Vendor assets go to wrong directories**
When `npm run build` copies vendor assets, `copyVendorFiles` resolves `css/vendors` and `js/vendors` from the repository root, while `Header::buildPathForModule()` serves Core assets from `src/Backend/Core/...`; webpack therefore writes vendor copies to unserved directories and leaves the served copies stale.
Resolve each vendor destination under its corresponding `src/Backend/Core` asset directory instead of the repository root.
</issue_to_address>
### Comment 5
<location path="webpack.dev.js" line_range="10-12" />
<code_context>
+ mode: 'development',
+ devtool: 'inline-source-map'
+ }),
+ merge(backend, {
+ mode: 'development'
+ })
+]
</code_context>
<issue_to_address>
**Backend Sass edits do not reload**
When a backend Sass file changes while `npm run watch` is running, the backend webpack compiler rebuilds its CSS without running the `BrowserSyncPlugin` hook, which is only registered in `webpack.common.js` for the separate theme compiler. The page stays stale until manually refreshed.
Configure BrowserSync to reload on backend compiler completion or watch the backend CSS output for changes.
</issue_to_address>
### Comment 6
<location path=".github/workflows/ci.yml" line_range="80" />
<code_context>
- run: |
- node_modules/.bin/gulp build
- npm run build
+ run: npm run build
</code_context>
<issue_to_address>
**CI no longer runs Gulp**
Both CI jobs now run `npm run build`, which invokes webpack; neither runs Gulp, so the recorded CI build fact is false.
Update the knowledge-base entry to reflect that CI now builds assets with webpack only.
Also at `.gitlab-ci.yml:53`.
</issue_to_address>Sourcery assessment
Approval pending. 3 findings to address first.
Blocking findings: package.json:35, webpack.backend.js:100, webpack.backend.js:9
| @@ -0,0 +1,144 @@ | |||
| const path = require('path') | |||
There was a problem hiding this comment.
⚪ Low · Backend build config is exposed
When a deployment uses the clear_paths list and serves the release through the repository’s .htaccess rules, deploy.php does not remove webpack.backend.js as it does the other webpack configs, and .htaccess does not block it; Apache serves the deployed file directly, exposing the backend asset build configuration to visitors.
Add webpack.backend.js to deploy.php’s clear_paths and explicitly block it in .htaccess for deployments that do not use that list.
Prompt for AI agents
In `webpack.backend.js` at line 1:
**Backend build config is exposed**
When a deployment uses the `clear_paths` list and serves the release through the repository’s `.htaccess` rules, `deploy.php` does not remove `webpack.backend.js` as it does the other webpack configs, and `.htaccess` does not block it; Apache serves the deployed file directly, exposing the backend asset build configuration to visitors.
Add `webpack.backend.js` to `deploy.php`’s `clear_paths` and explicitly block it in `.htaccess` for deployments that do not use that list.fork:theme:build still ran node_modules/.bin/gulp build before npm run build. Gulp is gone, so every deploy failed at that step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clear webpack.backend.js on deploy like the other webpack configs and block all webpack.*.js files in .htaccess. Drop the gulpfile.js entries, that file no longer exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The backend builds in its own webpack compiler, so BrowserSync only reloaded on theme changes. Watch the backend CSS output as well, like gulp serve did with livereload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path=".github/workflows/ci.yml" line_range="80" />
<code_context>
- run: |
- node_modules/.bin/gulp build
- npm run build
+ run: npm run build
</code_context>
<issue_to_address>
**CI no longer runs Gulp**
When the GitHub or GitLab asset-build job runs, both jobs now run only `npm run build`, so the knowledge-base fact that CI still uses the legacy Gulp pipeline is no longer true.
Update kb-423824 to reflect that CI now builds assets with webpack only.
Also at `.gitlab-ci.yml:53`.
</issue_to_address>Sourcery assessment
Approved.
Type
Resolves the following issues
The backend assets still built through a legacy
gulpfile.js(Gulp 4 and 6 gulp plugins), next to the webpack build for the theme. Two build tools, and CI ran both.Pull request description
Audit of the gulp tasks
All gulp output is committed to git, so dropping a task leaves the last built file in place.
Header.php, MediaLibrary, Pages,DatePickerType)codemirrorandlineutilsare not in the npm package (committed custom copies), duplicateiframeline removedscreen.scss,debug.scss)serve:*+ livereloadnpm run watchcovers itbootstrap.bundle.js,slick.min.jsCustom), frontend corescreen.cssis Bootstrap 3 on BS5 themes, photoswipe was replaced by fslightbox, bootstrap.bundle and slick are unreferencedChanges
webpack.backend.js, exported next to the theme config fromwebpack.dev.jsandwebpack.prod.js.gulpfile.jsand the gulp packages removed,webpack-remove-empty-scriptsadded.npm run buildonly.node_modulessilenced, no more emptyscreen.js/editor_content.js.Things that needed care
css-loaderruns withurl: false: the backend Sass uses absolute/src/...and/fonts/vendorsURLs.info.minimized), otherwise production mode re-minifies them.ckeditorJS ships with a UTF-8 BOM that gulp stripped. A copy transform strips it too, so the 655 committed files stay unchanged.Verification
npm run build: vendor copies and CKEditor byte-identical to git, backendscreen.csshas the same 2554 rules (whitespace-only diff), theme output byte-identical apart from the removed empty stubs.npm run watchrebuilds backend CSS on change.Follow-ups (not in this PR)
Frontend/Core/Layout/Css/screen.cssinFrontend/Core/Header/Header.php.Frontend/Modules/MediaLibrary/Widgets/Lightbox.phpfor BS5 themes.bootstrap@4,photoswipe,slick-carouselpackages.🤖 Generated with Claude Code
Summary by Sourcery
Consolidate theme and backend asset generation into a single webpack-based build and retire the legacy Gulp pipeline.
New Features:
Enhancements:
Build:
CI:
Deployment:
Documentation:
Chores: