Update to Webpack 5 and redesign build process.

This commit is contained in:
Buster "Silver Eagle" Neece 2021-09-11 15:46:31 -05:00
parent 2e98b94685
commit 8272aa5ef9
No known key found for this signature in database
GPG Key ID: 6D9E12FF03411F4E
11 changed files with 1820 additions and 11887 deletions

3
.gitignore vendored
View File

@ -34,6 +34,9 @@ tmp/cache/*---*
/web/static/dist/* /web/static/dist/*
/web/static/dist/**/* /web/static/dist/**/*
!/web/static/dist/.gitkeep !/web/static/dist/.gitkeep
/web/static/webpack_dist/*
/web/static/webpack_dist/**/*
!/web/static/webpack_dist/.gitkeep
/web/static/assets.json /web/static/assets.json
/web/static/webpack.json /web/static/webpack.json

View File

@ -42,22 +42,6 @@ return [
], ],
], ],
'vue-base' => [
'order' => 5,
'files' => [
'js' => [
[
'src' => 'dist/VueBase.js',
],
],
],
'inline' => [
'js' => [
'VueBase.default()',
],
],
],
'bootstrap-vue' => [ 'bootstrap-vue' => [
'order' => 4, 'order' => 4,
'files' => [ 'files' => [
@ -74,29 +58,6 @@ return [
], ],
], ],
'vue-component-common' => [
'order' => 4,
'require' => ['vue', 'vue-base'],
'files' => [
'js' => [
[
'src' => 'dist/vendor.js',
],
],
],
],
'lodash' => [
'order' => 2,
'files' => [
'js' => [
[
'src' => 'dist/lib/lodash/lodash.min.js',
],
],
],
],
/* /*
* Main per-layout dependencies * Main per-layout dependencies
*/ */
@ -450,81 +411,68 @@ return [
], ],
], ],
'leaflet' => [ 'Vue_Base' => [
'order' => 20, 'order' => 5,
'files' => [ 'require' => ['vue'],
// Auto-managed by Assets
'inline' => [
'js' => [ 'js' => [
[ 'Base.default()',
'src' => 'dist/lib/leaflet/leaflet.js',
'defer' => true,
],
[
'src' => 'dist/lib/leaflet-fullscreen/Control.FullScreen.js',
'defer' => true,
],
],
'css' => [
[
'href' => 'dist/lib/leaflet/leaflet.css',
],
[
'href' => 'dist/lib/leaflet-fullscreen/Control.FullScreen.css',
],
], ],
], ],
], ],
'Vue_Dashboard' => [ 'Vue_Dashboard' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'chartjs'], 'require' => ['Vue_Base', 'bootstrap-vue', 'uses-api', 'chartjs'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_PublicFullPlayer' => [ 'Vue_PublicFullPlayer' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment', 'fancybox'], 'require' => ['Vue_Base', 'bootstrap-vue', 'moment', 'fancybox'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_PublicHistory' => [ 'Vue_PublicHistory' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment'], 'require' => ['Vue_Base', 'bootstrap-vue', 'moment'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_AdminBranding' => [ 'Vue_AdminBranding' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox', 'codemirror'], 'require' => ['Vue_Base', 'bootstrap-vue', 'uses-api', 'fancybox', 'codemirror'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_AdminStorageLocations' => [ 'Vue_AdminStorageLocations' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue'], 'require' => ['Vue_Base', 'bootstrap-vue', 'uses-api'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_PublicOnDemand' => [ 'Vue_PublicOnDemand' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue'], 'require' => ['Vue_Base', 'bootstrap-vue'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_PublicRequests' => [ 'Vue_PublicRequests' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue'], 'require' => ['Vue_Base', 'bootstrap-vue'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_PublicSchedule' => [ 'Vue_PublicSchedule' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment_timezone'], 'require' => ['Vue_Base', 'bootstrap-vue', 'moment_timezone'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_PublicWebDJ' => [ 'Vue_PublicWebDJ' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common'], 'require' => ['Vue_Base'],
'files' => [ 'files' => [
'js' => [ 'js' => [
[ [
@ -545,67 +493,73 @@ return [
'Vue_StationsMedia' => [ 'Vue_StationsMedia' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'fancybox'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsMounts' => [ 'Vue_StationsMounts' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsPlaylists' => [ 'Vue_StationsPlaylists' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment_timezone'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'moment_timezone'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsPodcasts' => [ 'Vue_StationsPodcasts' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox', 'moment_timezone'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'fancybox', 'moment_timezone'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsPodcastEpisodes' => [ 'Vue_StationsPodcastEpisodes' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'fancybox', 'moment_timezone'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'fancybox', 'moment_timezone'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsProfile' => [ 'Vue_StationsProfile' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment', 'fancybox'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'moment', 'fancybox'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsQueue' => [ 'Vue_StationsQueue' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'moment'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsRemotes' => [ 'Vue_StationsRemotes' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsStreamers' => [ 'Vue_StationsStreamers' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'moment'],
// Auto-managed by Assets
],
'Vue_StationsReportsListeners' => [
'order' => 10,
'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'moment'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsReportsRequests' => [ 'Vue_StationsReportsRequests' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'moment'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'moment'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
'Vue_StationsReportsOverview' => [ 'Vue_StationsReportsOverview' => [
'order' => 10, 'order' => 10,
'require' => ['vue-component-common', 'uses-api', 'bootstrap-vue', 'chartjs'], 'require' => ['Vue_Base', 'uses-api', 'bootstrap-vue', 'chartjs'],
// Auto-managed by Assets // Auto-managed by Assets
], ],
]; ];

View File

@ -10,9 +10,8 @@ const sourcemaps = require('gulp-sourcemaps');
const sass = require('gulp-dart-sass'); const sass = require('gulp-dart-sass');
const clean_css = require('gulp-clean-css'); const clean_css = require('gulp-clean-css');
const revdel = require('gulp-rev-delete-original'); const revdel = require('gulp-rev-delete-original');
const webpackStream = require('webpack-stream');
const gulpIgnore = require('gulp-ignore');
const mode = require('gulp-mode')(); const mode = require('gulp-mode')();
const run = require('gulp-run-command').default;
var jsFiles = { var jsFiles = {
// Core Libraries // Core Libraries
@ -81,12 +80,6 @@ var jsFiles = {
}, },
// Individual libraries // Individual libraries
'store': {
base: 'node_modules/store',
files: [
'node_modules/store/store.min.js'
]
},
'zxcvbn': { 'zxcvbn': {
base: 'node_modules/zxcvbn/dist', base: 'node_modules/zxcvbn/dist',
files: [ files: [
@ -148,28 +141,6 @@ var jsFiles = {
'node_modules/@fancyapps/fancybox/dist/jquery.fancybox.min.*' 'node_modules/@fancyapps/fancybox/dist/jquery.fancybox.min.*'
] ]
}, },
'flowjs': {
base: 'node_modules/@flowjs/flow.js/dist',
files: [
'node_modules/@flowjs/flow.js/dist/flow.min.js'
]
},
'leaflet': {
base: 'node_modules/leaflet/dist',
files: [
'node_modules/leaflet/dist/leaflet.js',
'node_modules/leaflet/dist/leaflet.css',
'node_modules/leaflet/dist/images/*'
]
},
'leaflet-fullscreen': {
base: 'node_modules/leaflet.fullscreen',
files: [
'node_modules/leaflet.fullscreen/Control.FullScreen.js',
'node_modules/leaflet.fullscreen/Control.FullScreen.css',
'node_modules/leaflet.fullscreen/icon-*.png'
]
},
'nchan': { 'nchan': {
base: null, base: null,
files: [ files: [
@ -217,6 +188,7 @@ gulp.task('bundle_deps', gulp.parallel(
gulp.task('clean', function () { gulp.task('clean', function () {
return del([ return del([
'../web/static/dist/**/*', '../web/static/dist/**/*',
'../web/static/webpack_dist/**/*',
'../web/static/assets.json', '../web/static/assets.json',
'../web/static/webpack.json' '../web/static/webpack.json'
], { force: true }); ], { force: true });
@ -234,16 +206,7 @@ gulp.task('concat-js', function () {
.pipe(gulp.dest('../web/static/dist')); .pipe(gulp.dest('../web/static/dist'));
}); });
gulp.task('build-vue', function () { gulp.task('build-vue', run('webpack -c webpack.config.js'));
return gulp.src(['vue/*.js', 'vue/*.vue'])
.pipe(webpackStream(require('./webpack.config.js')))
.pipe(gulpIgnore.exclude('webpack.json'))
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(uglify())
.pipe(gulp.dest('../web/static/dist'));
});
gulp.task('build-js', function () { gulp.task('build-js', function () {
return gulp.src(['./js/*.js']) return gulp.src(['./js/*.js'])

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,8 @@
"ci": "npm run import-locales && npm run build" "ci": "npm run import-locales && npm run build"
}, },
"dependencies": { "dependencies": {
"@babel/core": "^7.13.16", "@babel/core": "^7.15.5",
"@babel/preset-env": "^7.13.15", "@babel/preset-env": "^7.15.6",
"@fancyapps/fancybox": "^3.5.7", "@fancyapps/fancybox": "^3.5.7",
"@flowjs/flow.js": "^2.14.1", "@flowjs/flow.js": "^2.14.1",
"@fullcalendar/core": "^4", "@fullcalendar/core": "^4",
@ -21,7 +21,7 @@
"@fullcalendar/timegrid": "^4", "@fullcalendar/timegrid": "^4",
"@fullcalendar/vue": "^4", "@fullcalendar/vue": "^4",
"autosize": "^4.0.2", "autosize": "^4.0.2",
"axios": "^0.21.1", "axios": "^0.21.4",
"bootstrap": "^4.6.0", "bootstrap": "^4.6.0",
"bootstrap-daterangepicker": "^3.1.0", "bootstrap-daterangepicker": "^3.1.0",
"bootstrap-notify": "^3.1.3", "bootstrap-notify": "^3.1.3",
@ -30,7 +30,7 @@
"chartjs-plugin-colorschemes": "^0.3.0", "chartjs-plugin-colorschemes": "^0.3.0",
"chartjs-plugin-zoom": "^0.7.7", "chartjs-plugin-zoom": "^0.7.7",
"clipboard": "^2.0.8", "clipboard": "^2.0.8",
"codemirror": "^5.61.0", "codemirror": "^5.62.3",
"css-loader": "^1.0", "css-loader": "^1.0",
"del": "^3.0.0", "del": "^3.0.0",
"dirrty": "^1.0.0", "dirrty": "^1.0.0",
@ -40,10 +40,10 @@
"gulp-clean-css": "^3.9.2", "gulp-clean-css": "^3.9.2",
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"gulp-dart-sass": "^1.0.2", "gulp-dart-sass": "^1.0.2",
"gulp-ignore": "^3.0.0",
"gulp-mode": "^1.1.0", "gulp-mode": "^1.1.0",
"gulp-rev": "^8.1.1", "gulp-rev": "^8.1.1",
"gulp-rev-delete-original": "^0.2.3", "gulp-rev-delete-original": "^0.2.3",
"gulp-run-command": "0.0.10",
"gulp-sourcemaps": "^2.6.5", "gulp-sourcemaps": "^2.6.5",
"gulp-uglify": "^3.0.2", "gulp-uglify": "^3.0.2",
"jquery": "^3.6.0", "jquery": "^3.6.0",
@ -57,23 +57,26 @@
"popper.js": "^1.16.1", "popper.js": "^1.16.1",
"prettier": "1.12.1", "prettier": "1.12.1",
"roboto-fontface": "^0.10.0", "roboto-fontface": "^0.10.0",
"sass": "^1.32.12", "sass": "^1.39.2",
"sass-loader": "^7.3.1", "sass-loader": "^7.3.1",
"select2": "^4.0.13", "select2": "^4.0.13",
"sortablejs": "^1.13.0", "sortablejs": "^1.14.0",
"store": "^1.3.20", "store": "^1.3.20",
"sweetalert2": "^10.16.6", "sweetalert2": "^10.16.6",
"vue": "^2.6.12", "vue": "^2.6.14",
"vue-axios": "^3.2.5", "vue-axios": "^3.3.6",
"vue-gettext": "^2.1.12", "vue-gettext": "^2.1.12",
"vue-loader": "14.2.2", "vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.12", "vue-template-compiler": "^2.6.14",
"vue2-daterange-picker": "^0.6.6",
"vue2-leaflet": "^2.7.1",
"vue2-leaflet-fullscreen": "^1.0.1",
"vuedraggable": "^2.24.1", "vuedraggable": "^2.24.1",
"vuelidate": "^0.7.5", "vuelidate": "^0.7.6",
"wavesurfer.js": "^3.3.3", "wavesurfer.js": "^3.3.3",
"webpack": "^4.46.0", "webpack": "^5.52.1",
"webpack-assets-manifest": "^3.1.1", "webpack-assets-manifest": "^3.1.1",
"webpack-stream": "^5.1.1", "webpack-cli": "^4.8.0",
"zxcvbn": "^4.4.2" "zxcvbn": "^4.4.2"
} }
} }

View File

@ -7,7 +7,7 @@ import GetTextPlugin
import translations import translations
from '../../resources/locale/translations'; from '../../resources/locale/translations';
export default function (lang, csrf) { export default function () {
// Configure localization // Configure localization
Vue.use(GetTextPlugin, { Vue.use(GetTextPlugin, {
defaultLanguage: 'en_US', defaultLanguage: 'en_US',

View File

@ -1,10 +1,12 @@
const webpack = require('webpack'); const webpack = require('webpack');
const WebpackAssetsManifest = require('webpack-assets-manifest'); const WebpackAssetsManifest = require('webpack-assets-manifest');
const { VueLoaderPlugin } = require('vue-loader');
const path = require('path');
module.exports = { module.exports = {
mode: 'production', mode: 'development',
entry: { entry: {
VueBase: './vue/VueBase.js', Base: './vue/VueBase.js',
InlinePlayer: './vue/InlinePlayer.vue', InlinePlayer: './vue/InlinePlayer.vue',
Dashboard: './vue/Dashboard.vue', Dashboard: './vue/Dashboard.vue',
AdminBranding: './vue/Admin/Branding.vue', AdminBranding: './vue/Admin/Branding.vue',
@ -24,17 +26,21 @@ module.exports = {
StationsQueue: './vue/Stations/Queue.vue', StationsQueue: './vue/Stations/Queue.vue',
StationsRemotes: './vue/Stations/Remotes.vue', StationsRemotes: './vue/Stations/Remotes.vue',
StationsStreamers: './vue/Stations/Streamers.vue', StationsStreamers: './vue/Stations/Streamers.vue',
StationsReportsListeners: './vue/Stations/Reports/Listeners.vue',
StationsReportsRequests: './vue/Stations/Reports/Requests.vue', StationsReportsRequests: './vue/Stations/Reports/Requests.vue',
StationsReportsOverview: './vue/Stations/Reports/Overview.vue' StationsReportsOverview: './vue/Stations/Reports/Overview.vue'
}, },
resolve: { resolve: {
extensions: ['*', '.js', '.vue', '.json'] enforceExtension: false,
extensions: ['.js', '.vue', '.json']
}, },
output: { output: {
publicPath: 'dist/', path: path.resolve(__dirname, '../web/static/webpack_dist'),
filename: '[name].js', publicPath: '/static/webpack_dist/',
sourceMapFilename: '[name].map', filename: '[name].[contenthash].js',
library: '[name]' sourceMapFilename: '[name].[contenthash].map',
library: '[name]',
assetModuleFilename: 'images/[contenthash][ext]'
}, },
optimization: { optimization: {
splitChunks: { splitChunks: {
@ -53,6 +59,20 @@ module.exports = {
chunks: 'initial', chunks: 'initial',
enforce: true enforce: true
}, },
leaflet: {
test: /[\\/]node_modules[\\/]leaflet/,
name: 'vendor-leaflet',
priority: 2,
chunks: 'initial',
enforce: true
},
vuelidate: {
test: /[\\/]node_modules[\\/]vuelidate/,
name: 'vendor-vuelidate',
priority: 2,
chunks: 'initial',
enforce: true
},
vendor: { vendor: {
test: /[\\/]node_modules[\\/]/, test: /[\\/]node_modules[\\/]/,
name: 'vendor', name: 'vendor',
@ -65,24 +85,43 @@ module.exports = {
module: { module: {
rules: [ rules: [
{ {
test: /\.vue$/, test: /\.vue$/i,
loader: 'vue-loader' use: [
'vue-loader'
]
}, },
{ {
test: /\.scss$/, test: /\.scss$/i,
loader: 'vue-style-loader' use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.css$/i,
use: [
'vue-style-loader',
'css-loader'
]
},
{
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
type: 'asset/resource'
} }
] ]
}, },
plugins: [ plugins: [
new WebpackAssetsManifest({ new WebpackAssetsManifest({
output: '../web/static/webpack.json', output: path.resolve(__dirname, '../web/static/webpack.json'),
writeToDisk: true, writeToDisk: true,
merge: true, merge: true,
publicPath: true, publicPath: true,
entrypoints: true entrypoints: true
}) }),
new VueLoaderPlugin()
], ],
target: 'web',
performance: { performance: {
hints: false hints: false
} }

View File

@ -73,16 +73,14 @@ class Assets
'files' => [], 'files' => [],
]; ];
if (!in_array('vue-component-common', $library['require'], true)) { if ($componentName !== 'Vue_Base' && !in_array('Vue_Base', $library['require'], true)) {
$library['require'][] = 'vue-component-common'; $library['require'][] = 'Vue_Base';
} }
foreach ($componentDeps['js'] as $componentDep) { foreach ($componentDeps['js'] as $componentDep) {
if ('dist/vendor.js' !== $componentDep) { $library['files']['js'][] = [
$library['files']['js'][] = [ 'src' => $componentDep,
'src' => $componentDep, ];
];
}
} }
$this->addLibrary($library, $componentName); $this->addLibrary($library, $componentName);
@ -330,7 +328,7 @@ class Assets
foreach ($this->loaded as $item) { foreach ($this->loaded as $item) {
if (!empty($item['files']['css'])) { if (!empty($item['files']['css'])) {
foreach ($item['files']['css'] as $file) { foreach ($item['files']['css'] as $file) {
$compiled_attributes = $this->compileAttributes( $attributes = $this->resolveAttributes(
$file, $file,
[ [
'rel' => 'stylesheet', 'rel' => 'stylesheet',
@ -338,7 +336,12 @@ class Assets
] ]
); );
$result[] = '<link ' . implode(' ', $compiled_attributes) . ' />'; $key = $attributes['href'];
if (isset($result[$key])) {
continue;
}
$result[$key] = '<link ' . implode(' ', $this->compileAttributes($attributes)) . ' />';
} }
} }
@ -372,14 +375,19 @@ class Assets
foreach ($this->loaded as $item) { foreach ($this->loaded as $item) {
if (!empty($item['files']['js'])) { if (!empty($item['files']['js'])) {
foreach ($item['files']['js'] as $file) { foreach ($item['files']['js'] as $file) {
$compiled_attributes = $this->compileAttributes( $attributes = $this->resolveAttributes(
$file, $file,
[ [
'type' => 'text/javascript', 'type' => 'text/javascript',
] ]
); );
$result[] = '<script ' . implode(' ', $compiled_attributes) . '></script>'; $key = $attributes['src'];
if (isset($result[$key])) {
continue;
}
$result[$key] = '<script ' . implode(' ', $this->compileAttributes($attributes)) . '></script>';
} }
} }
} }
@ -434,15 +442,7 @@ class Assets
} }
} }
/** protected function resolveAttributes(array $file, array $defaults): array
* Build the proper include tag for a JS/CSS include.
*
* @param array $file
* @param array $defaults
*
* @return string[]
*/
protected function compileAttributes(array $file, array $defaults = []): array
{ {
if (isset($file['src'])) { if (isset($file['src'])) {
$defaults['src'] = $this->getUrl($file['src']); $defaults['src'] = $this->getUrl($file['src']);
@ -458,8 +458,18 @@ class Assets
$defaults['crossorigin'] = 'anonymous'; $defaults['crossorigin'] = 'anonymous';
} }
$attributes = array_merge($defaults, $file); return array_merge($defaults, $file);
}
/**
* Build the proper include tag for a JS/CSS include.
*
* @param array $attributes
*
* @return string[]
*/
protected function compileAttributes(array $attributes): array
{
$compiled_attributes = []; $compiled_attributes = [];
foreach ($attributes as $attr_key => $attr_val) { foreach ($attributes as $attr_key => $attr_val) {
// Check for attributes like "defer" // Check for attributes like "defer"
@ -520,6 +530,10 @@ class Assets
return $resource_uri; return $resource_uri;
} }
if (str_starts_with($resource_uri, '/')) {
return $resource_uri;
}
return $this->environment->getAssetUrl() . '/' . $resource_uri; return $this->environment->getAssetUrl() . '/' . $resource_uri;
} }

View File

@ -72,6 +72,9 @@ server {
location /static/dist { location /static/dist {
expires 365d; expires 365d;
} }
location /static/webpack_dist {
expires 365d;
}
location ~ \.php$ { location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_split_path_info ^(.+\.php)(/.+)$;

View File

@ -109,6 +109,9 @@ server {
location /static/dist { location /static/dist {
expires 365d; expires 365d;
} }
location /static/webpack_dist {
expires 365d;
}
location ~ ^/index\.php(/|$) { location ~ ^/index\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_split_path_info ^(.+\.php)(/.+)$;

View File

@ -0,0 +1 @@
.gitkeep