Improve Jqhtml_Integration.js documentation with hydration system explanation Add jqhtml-laravel integration packages for traditional Laravel projects 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
198 lines
5.6 KiB
JavaScript
198 lines
5.6 KiB
JavaScript
let path = require('path');
|
|
let Entry = require('./Entry');
|
|
let webpackRules = require('./webpack-rules');
|
|
let webpackPlugins = require('./webpack-plugins');
|
|
let webpackDefaultConfig = require('./webpack-default');
|
|
|
|
class WebpackConfig {
|
|
/**
|
|
* Create a new instance.
|
|
*
|
|
* @param {import("../Mix.js")} mix
|
|
*/
|
|
constructor(mix) {
|
|
this.mix = mix;
|
|
this.chunks = mix.chunks;
|
|
|
|
/** @type {ReturnType<webpackDefaultConfig>} */
|
|
this.webpackConfig = {};
|
|
}
|
|
|
|
/**
|
|
* Build the Webpack configuration object.
|
|
*/
|
|
async build() {
|
|
this.webpackConfig = webpackDefaultConfig(this.mix);
|
|
|
|
await this.buildEntry();
|
|
this.buildOutput();
|
|
this.configureHMR();
|
|
await this.buildRules();
|
|
await this.buildPlugins();
|
|
this.buildChunks();
|
|
|
|
// We'll announce that the core config object has been
|
|
// generated by Mix. At this point, any plugins may
|
|
// hook in and modify the config as necessary.
|
|
await this.mix.dispatch('configReady', this.webpackConfig);
|
|
|
|
// Rebuild the chunks as plugins may have added new ones
|
|
this.buildChunks();
|
|
|
|
// Finally, we'll make one last announcement for the user
|
|
// to hook into - using mix.override().
|
|
await this.mix.dispatch('configReadyForUser', this.webpackConfig);
|
|
|
|
// Rebuild the chunks as the user may have changed things
|
|
this.buildChunks();
|
|
|
|
return this.webpackConfig;
|
|
}
|
|
|
|
/**
|
|
* Build the entry object.
|
|
*/
|
|
async buildEntry() {
|
|
let entry = new Entry(this.mix);
|
|
|
|
if (!this.mix.bundlingJavaScript) {
|
|
entry.addDefault();
|
|
}
|
|
|
|
await this.mix.dispatch('loading-entry', entry);
|
|
|
|
this.webpackConfig.entry = entry.get();
|
|
}
|
|
|
|
/**
|
|
* Build the output object.
|
|
*/
|
|
buildOutput() {
|
|
this.webpackConfig.output = {
|
|
hashFunction: 'xxhash64',
|
|
path: path.resolve(this.mix.config.publicPath),
|
|
filename: '[name].js',
|
|
|
|
chunkFilename: pathData => {
|
|
let hasAbsolutePathChunkName =
|
|
pathData.chunk &&
|
|
pathData.chunk.name &&
|
|
pathData.chunk.name.startsWith('/');
|
|
|
|
if (
|
|
(this.mix.components.get('js') || this.mix.components.get('ts')) &&
|
|
!hasAbsolutePathChunkName
|
|
) {
|
|
let output = this.mix.components.get('ts')
|
|
? this.mix.components.get('ts').toCompile[0].output
|
|
: this.mix.components.get('js').toCompile[0].output;
|
|
|
|
return `${output.normalizedOutputPath()}/[name].js`;
|
|
}
|
|
|
|
return '[name].js';
|
|
},
|
|
|
|
publicPath: '/'
|
|
};
|
|
}
|
|
|
|
configureHMR() {
|
|
if (!this.mix.isUsing('hmr')) {
|
|
return;
|
|
}
|
|
|
|
// TODO: Centralize this code between HotReloading and here…
|
|
// It's duplicated
|
|
const { https, host, port } = this.mix.config.hmrOptions;
|
|
const protocol = https ? 'https' : 'http';
|
|
const url = `${protocol}://${host}:${port}/`;
|
|
|
|
this.webpackConfig.output = {
|
|
...this.webpackConfig.output,
|
|
|
|
publicPath: url
|
|
};
|
|
|
|
this.webpackConfig.devServer = {
|
|
host,
|
|
port,
|
|
|
|
client: {
|
|
webSocketURL: {
|
|
hostname: host,
|
|
pathname: '/ws',
|
|
port
|
|
}
|
|
},
|
|
|
|
liveReload: false,
|
|
|
|
https,
|
|
|
|
devMiddleware: {
|
|
headers: {
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
|
|
'Access-Control-Allow-Headers':
|
|
'X-Requested-With, Content-Type, Authorization'
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
* @param {{app: import("express").Application}} param0
|
|
*/
|
|
onBeforeSetupMiddleware({ app }) {
|
|
app.use(function (req, _, next) {
|
|
// Something causes hot update chunks (except for the JSON payload)
|
|
// to start with a double slash
|
|
// e.g. GET http://localhost:8080//js/app.[hash].hot-update.js
|
|
|
|
// This causes loading those chunks to fail so we patch it up here
|
|
// This is super hacky and a proper solution should be found eventually
|
|
req.url = req.url.replace(/^\/\//, '/');
|
|
|
|
next();
|
|
});
|
|
},
|
|
|
|
...this.webpackConfig.devServer
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Build the rules array.
|
|
*/
|
|
async buildRules() {
|
|
this.webpackConfig.module = this.webpackConfig.module || {};
|
|
this.webpackConfig.module.rules = this.webpackConfig.module.rules || [];
|
|
|
|
this.webpackConfig.module.rules.push(...webpackRules(this.mix));
|
|
|
|
await this.mix.dispatch('loading-rules', this.webpackConfig.module.rules);
|
|
}
|
|
|
|
/**
|
|
* Build the plugins array.
|
|
*/
|
|
async buildPlugins() {
|
|
this.webpackConfig.plugins = this.webpackConfig.plugins || [];
|
|
this.webpackConfig.plugins.push(...webpackPlugins(this.mix));
|
|
|
|
await this.mix.dispatch('loading-plugins', this.webpackConfig.plugins);
|
|
}
|
|
|
|
/**
|
|
* Build the resolve object.
|
|
*/
|
|
buildChunks() {
|
|
this.webpackConfig = require('./MergeWebpackConfig')(
|
|
this.webpackConfig,
|
|
this.mix.chunks.config()
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = WebpackConfig;
|