Auto-load most Vue component deps from Webpack manifest.

This commit is contained in:
Buster "Silver Eagle" Neece 2020-07-15 03:00:17 -05:00
parent b572b3dbc7
commit ffa6d6b4fc
No known key found for this signature in database
GPG Key ID: 6D9E12FF03411F4E
17 changed files with 153 additions and 84 deletions

1
.gitignore vendored
View File

@ -36,6 +36,7 @@ tmp/cache/*---*
/web/static/dist/**/*
!/web/static/dist/.gitkeep
/web/static/assets.json
/web/static/webpack.json
# Ansible deployment files
/ansible/

View File

@ -445,7 +445,7 @@ return [
],
],
'webcaster' => [
'Webcaster' => [
'order' => 10,
'require' => ['vue-component-common'],
'files' => [
@ -462,83 +462,32 @@ return [
[
'src' => 'dist/lib/webcaster/webcast.js',
],
[
'src' => 'dist/Webcaster.js',
],
],
],
],
'radio_player' => [
'order' => 10,
'require' => ['vue-component-common'],
'files' => [
'js' => [
[
'src' => 'dist/RadioPlayer.js',
],
],
],
],
'inline_player' => [
'order' => 10,
'require' => ['vue-component-common'],
'files' => [
'js' => [
[
'src' => 'dist/InlinePlayer.js',
],
],
],
],
'station_media_manager' => [
'StationMedia' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue'],
'files' => [
'js' => [
[
'src' => 'dist/StationMedia.js',
],
],
],
// Auto-managed by Assets
],
'station_playlists' => [
'StationPlaylists' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment_base', 'moment_timezone'],
'replace' => ['moment'],
'files' => [
'js' => [
[
'src' => 'dist/StationPlaylists.js',
],
],
],
// Auto-managed by Assets
],
'station_streamers' => [
'StationStreamers' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue', 'moment'],
'files' => [
'js' => [
[
'src' => 'dist/StationStreamers.js',
],
],
],
// Auto-managed by Assets
],
'station_on_demand' => [
'StationOnDemand' => [
'order' => 10,
'require' => ['vue-component-common', 'bootstrap-vue'],
'files' => [
'js' => [
[
'src' => 'dist/StationOnDemand.js',
],
],
],
// Auto-managed by Assets
],
];

View File

@ -367,7 +367,13 @@ return [
$versioned_files = json_decode(file_get_contents($assets_file), true, 512, JSON_THROW_ON_ERROR);
}
return new App\Assets($libraries, $versioned_files);
$vueComponents = [];
$assets_file = $settings[Settings::BASE_DIR] . '/web/static/webpack.json';
if (file_exists($assets_file)) {
$vueComponents = json_decode(file_get_contents($assets_file), true, 512, JSON_THROW_ON_ERROR);
}
return new App\Assets($libraries, $versioned_files, $vueComponents);
},
// Synchronized (Cron) Tasks

View File

@ -11,6 +11,7 @@ const sass = require('gulp-sass');
const clean_css = require('gulp-clean-css');
const revdel = require('gulp-rev-delete-original');
const webpackStream = require('webpack-stream');
const gulpIgnore = require('gulp-ignore');
var jsFiles = {
// Core Libraries
@ -216,7 +217,8 @@ gulp.task('bundle_deps', gulp.parallel(
gulp.task('clean', function () {
return del([
'../web/static/dist/**/*',
'../web/static/assets.json'
'../web/static/assets.json',
'../web/static/webpack.json'
], { force: true });
});
@ -234,13 +236,12 @@ gulp.task('concat-js', function () {
gulp.task('build-vue', function () {
return gulp.src(['vue/*.js', 'vue/*.vue'])
.pipe(sourcemaps.init())
.pipe(webpackStream(require('./webpack.config.js')))
.pipe(gulpIgnore.exclude('webpack.json'))
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(uglify())
.pipe(sourcemaps.write())
.pipe(gulp.dest('../web/static/dist'));
});

View File

@ -14397,6 +14397,37 @@
"vinyl": "^2.0.0"
}
},
"gulp-ignore": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/gulp-ignore/-/gulp-ignore-3.0.0.tgz",
"integrity": "sha512-hRQDJipaU5A84J7QacNGG+bnFU3QLESdjuJCRTAZ5VuKsz4LmvOrECFJeeCtqxP3RV0Pn6mawU0Q3CFZGpirSg==",
"dev": true,
"requires": {
"gulp-match": "^1.1.0",
"through2": "^3.0.1"
},
"dependencies": {
"through2": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
"dev": true,
"requires": {
"inherits": "^2.0.4",
"readable-stream": "2 || 3"
}
}
}
},
"gulp-match": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.1.0.tgz",
"integrity": "sha512-DlyVxa1Gj24DitY2OjEsS+X6tDpretuxD6wTfhXE/Rw2hweqc1f6D/XtsJmoiCwLWfXgR87W9ozEityPCVzGtQ==",
"dev": true,
"requires": {
"minimatch": "^3.0.3"
}
},
"gulp-rev": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/gulp-rev/-/gulp-rev-8.1.1.tgz",
@ -15412,6 +15443,18 @@
"integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=",
"dev": true
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"lodash.has": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz",
"integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=",
"dev": true
},
"lodash.some": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
@ -19112,6 +19155,21 @@
"webpack-sources": "^1.4.1"
}
},
"webpack-assets-manifest": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/webpack-assets-manifest/-/webpack-assets-manifest-3.1.1.tgz",
"integrity": "sha512-JV9V2QKc5wEWQptdIjvXDUL1ucbPLH2f27toAY3SNdGZp+xSaStAgpoMcvMZmqtFrBc9a5pTS1058vxyMPOzRQ==",
"dev": true,
"requires": {
"chalk": "^2.0",
"lodash.get": "^4.0",
"lodash.has": "^4.0",
"mkdirp": "^0.5",
"schema-utils": "^1.0.0",
"tapable": "^1.0.0",
"webpack-sources": "^1.0.0"
}
},
"webpack-sources": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",

View File

@ -61,6 +61,7 @@
"gulp-babel": "^8.0.0",
"gulp-clean-css": "^3.9.2",
"gulp-concat": "^2.6.1",
"gulp-ignore": "^3.0.0",
"gulp-rev": "^8.1.1",
"gulp-rev-delete-original": "^0.2.3",
"gulp-sass": "^4.1.0",
@ -71,6 +72,7 @@
"sass-loader": "^7.3.1",
"vue-loader": "14.2.2",
"vue-template-compiler": "^2.6.11",
"webpack-assets-manifest": "^3.1.1",
"webpack-stream": "^5.1.1"
}
}

View File

@ -1,4 +1,5 @@
const webpack = require('webpack');
const WebpackAssetsManifest = require('webpack-assets-manifest');
module.exports = {
mode: 'production',
@ -16,7 +17,7 @@ module.exports = {
extensions: ['*', '.js', '.vue', '.json']
},
output: {
publicPath: '/static/dist',
publicPath: 'dist/',
filename: '[name].js',
sourceMapFilename: '[name].map',
library: '[name]'
@ -24,10 +25,24 @@ module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
moment: {
test: /[\\/]node_modules[\\/]moment/,
name: 'vendor-moment',
priority: 2,
chunks: 'initial',
enforce: true
},
fullcalendar: {
test: /[\\/]node_modules[\\/]@fullcalendar/,
name: 'vendor-fullcalendar',
priority: 2,
chunks: 'initial',
enforce: true
},
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'initial',
enforce: true
}
}
@ -51,8 +66,12 @@ module.exports = {
]
},
plugins: [
new webpack.IgnorePlugin({
resourceRegExp: /^vue$/
new WebpackAssetsManifest({
output: '../web/static/webpack.json',
writeToDisk: true,
merge: true,
publicPath: true,
entrypoints: true
})
],
performance: {

View File

@ -42,17 +42,50 @@ class Assets
*
* @throws \Exception
*/
public function __construct(array $libraries = [], array $versioned_files = [])
{
public function __construct(
array $libraries = [],
array $versioned_files = [],
array $vueComponents = []
) {
foreach ($libraries as $library_name => $library) {
$this->addLibrary($library, $library_name);
}
$this->versioned_files = $versioned_files;
$this->addVueComponents($vueComponents);
$this->csp_nonce = preg_replace('/[^A-Za-z0-9\+\/=]/', '', base64_encode(random_bytes(18)));
$this->csp_domains = [];
}
protected function addVueComponents(array $vueComponents = [])
{
if (!empty($vueComponents['entrypoints'])) {
foreach ($vueComponents['entrypoints'] as $componentName => $componentDeps) {
$library = $this->libraries[$componentName] ?? [
'order' => 10,
'require' => [],
'files' => [],
];
if (!in_array('vue-component-common', $library['require'], true)) {
$library['require'][] = 'vue-component-common';
}
foreach ($componentDeps['js'] as $componentDep) {
if ('dist/vendor.js' !== $componentDep) {
$library['files']['js'][] = [
'src' => $componentDep,
];
}
}
$this->addLibrary($library, $componentName);
}
}
}
/**
* Add a library to the collection.
*

View File

@ -12,7 +12,7 @@ $this->layout('main', ['title' => __('Dashboard'), 'manual' => true]);
$assets
->load('vue')
->load('inline_player')
->load('InlinePlayer')
->addInlineJs($this->fetch('partials/radio_controls.js'), 95)
->addInlineJs($this->fetch('frontend/index/index.js', ['stations' => $stations]));

View File

@ -1,14 +1,14 @@
<?php
$this->layout('minimal', [
'page_class' => 'dj station-'.$station->getShortName(),
'title' => 'Web DJ - '.$this->e($station->getName()),
'hide_footer' => true
'page_class' => 'dj station-' . $station->getShortName(),
'title' => 'Web DJ - ' . $this->e($station->getName()),
'hide_footer' => true,
]);
/** @var \App\Assets $assets */
$assets
->load('vue')
->load('webcaster')
->load('Webcaster')
->addInlineJs($this->fetch('frontend/public/dj.js', ['station' => $station, 'base_uri' => $base_uri]));
?>
<section id="content" role="main" style="height: 100vh;">

View File

@ -9,7 +9,7 @@ $this->layout('minimal', [
$assets
->load('vue')
->load('fancybox')
->load('station_on_demand')
->load('StationOnDemand')
->addInlineJs($this->fetch('frontend/public/ondemand.js', [
'station' => $station,
'custom_fields' => $custom_fields,

View File

@ -8,7 +8,7 @@ $this->layout('minimal', [
/** @var \App\Assets $assets */
$assets
->load('vue')
->load('station_on_demand')
->load('StationOnDemand')
->addInlineJs($this->fetch('frontend/public/ondemand.js', [
'station' => $station,
'custom_fields' => $custom_fields,

View File

@ -1,7 +1,7 @@
<?php
/** @var \App\Assets $assets */
$assets
->load('radio_player')
->load('RadioPlayer')
->addInlineJs($this->fetch('frontend/public/player_component.js', [
'station' => $station,
'nowplaying' => $nowplaying,

View File

@ -10,8 +10,8 @@ $assets
->load('vue')
->load('moment')
->load('fancybox')
->load('inline_player')
->load('station_media_manager')
->load('InlinePlayer')
->load('StationMedia')
->addInlineJs($this->fetch('partials/radio_controls.js'), 95)
->addInlineJs($this->fetch('stations/files/index.js', [
'playlists' => $playlists,

View File

@ -5,7 +5,7 @@ $this->layout('main', [
]);
/** @var \App\Assets $assets */
$assets->load('station_playlists')
$assets->load('StationPlaylists')
->addInlineJs($this->fetch('stations/playlists/index.js', [
'station_tz' => $station_tz,
]));

View File

@ -12,7 +12,7 @@ $this->layout('main', [
$assets
->load('vue')
->load('inline_player')
->load('InlinePlayer')
->addInlineJs($this->fetch('partials/radio_controls.js'), 95)
->load('clipboard')
->load('fancybox')

View File

@ -2,7 +2,7 @@
$this->layout('main', ['title' => __('Streamer/DJ Accounts'), 'manual' => true]);
/** @var \App\Assets $assets */
$assets->load('station_streamers')
$assets->load('StationStreamers')
->addInlineJs($this->fetch('stations/streamers/index.js', [
'station_tz' => $station_tz,
]));