Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
PORT=3506 # Free TCP port
SERVER_ADDRESS=domain.local # Your PrestaShop domain
SITE_URL=http://domain.local # Your PrestaShop URL
PUBLIC_PATH=/themes/hummingbird/assets/ # Your theme's public path

View File

@@ -0,0 +1,39 @@
const { merge } = require('webpack-merge');
const path = require('path');
const {
extractScss, extractJs, extractImages, extractFonts, externals, expose, preloadFonts
} = require('./webpack.parts');
exports.commonConfig = ({
mode, port, publicPath, siteURL, getOutput, getEntry, entriesArray, serverAddress,
}) => (
merge(
expose(),
{
mode,
entry: getEntry(entriesArray),
output: getOutput({
mode, publicPath, siteURL, port, serverAddress,
}),
target: 'web',
resolve: {
alias: {
'@js': path.resolve(__dirname, '../src/js'),
'@services': path.resolve(__dirname, '../src/js/services'),
'@constants': path.resolve(__dirname, '../src/js/constants'),
'@helpers': path.resolve(__dirname, '../src/js/helpers'),
},
},
stats: {
warnings: false,
},
},
externals(),
expose(),
extractScss({ mode }),
extractJs(),
extractImages(),
extractFonts(),
preloadFonts(),
)
);

View File

@@ -0,0 +1,26 @@
const { configureDevServer } = require('./webpack.parts');
const { HotAcceptPlugin } = require('hot-accept-webpack-plugin');
const webpack = require('webpack');
exports.developmentConfig = ({ port, publicPath, serverAddress, siteURL, entriesArray, isDevServer = false }) => {
const plugins = [];
// Only enable HMR when using webpack serve (dev server)
if (isDevServer) {
plugins.push(
new webpack.HotModuleReplacementPlugin(),
new HotAcceptPlugin({
test: Object.keys(entriesArray).map(el => `${el}.js`)
})
);
}
return {
devtool: "source-map",
devServer: isDevServer ? configureDevServer(serverAddress, publicPath, port, siteURL) : undefined,
watchOptions: {
ignored: /node_modules/,
},
plugins
};
};

View File

@@ -0,0 +1,215 @@
const path = require('path');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const FontPreloadPlugin = require('webpack-font-preload-plugin');
exports.configureDevServer = (serverAddress, publicPath, port, siteURL) => ({
allowedHosts: [serverAddress],
host: serverAddress,
client: {
logging: 'error',
progress: false,
overlay: {
errors: true,
warnings: false,
},
},
devMiddleware: {
publicPath,
writeToDisk: (filePath) => !(/\.hot-update\./.test(filePath)),
},
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
// 🚫 Disable browser caching
'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
'Surrogate-Control': 'no-store',
},
hot: true,
liveReload: true,
watchFiles: [
'../../**/*.tpl',
'../../modules/**/*.ts',
'../../modules/**/*.css',
],
port,
proxy: [{
context: '**',
target: siteURL,
secure: false,
changeOrigin: true,
}],
static: {
publicPath,
},
});
exports.extractScss = ({mode = 'production'}) => ({
module: {
rules: [{
test: /\.scss$/,
exclude: /_rtl\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
config: path.resolve(__dirname, '../postcss.config.js'),
},
},
},
'sass-loader',
],
},
{
test: /_rtl\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: path.resolve('./webpack/webpack.rtl.js'),
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
config: path.resolve(__dirname, '../postcss.config.js'),
},
},
},
'sass-loader',
],
}],
},
plugins: [
new RemoveEmptyScriptsPlugin(),
new MiniCssExtractPlugin({
filename: 'css/[name].css',
chunkFilename: mode === 'production' ? 'css/[chunkhash].css' : 'css/[id].css',
}),
],
});
exports.extractJs = () => ({
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)?$/,
exclude: /(node_modules)/,
resolve: {
fullySpecified: false,
extensions: ['.js', '.ts'],
},
use: {
loader: 'esbuild-loader',
options: {
loader: 'ts',
target: 'es2015',
},
},
},
],
},
plugins: [
new ForkTsCheckerWebpackPlugin(),
],
});
exports.extractImages = () => ({
module: {
rules: [
{
test: /\.(png|jpg|gif|svg)$/,
type: 'asset/resource',
generator: {
outputPath: 'img-dist/',
publicPath: '../img-dist/',
filename: '[contenthash][ext]',
},
},
],
},
});
exports.extractFonts = () => ({
module: {
rules: [
{
test: /\.(woff|woff2|ttf|eot|otf)$/,
type: 'asset/resource',
generator: {
outputPath: 'fonts/',
publicPath: '../fonts/',
filename: '[name]-[contenthash][ext]',
},
},
],
},
});
exports.cleanDistFolders = () => ({
plugins: [
new CleanWebpackPlugin({
dry: false,
dangerouslyAllowCleanPatternsOutsideProject: true,
cleanOnceBeforeBuildPatterns: [
path.join(__dirname, '../../assets/js/**'),
path.join(__dirname, '../../assets/css/**'),
path.join(__dirname, '../../assets/img-dist/**'),
path.join(__dirname, '../../assets/fonts/**'),
],
}),
],
});
exports.externals = () => ({
externals: {
prestashop: 'prestashop',
},
});
exports.preloadFonts = () => ({
plugins: [
new HtmlWebpackPlugin({
filename: 'preload.html',
templateContent: '{{{preloadLinks}}}',
inject: false,
}),
new FontPreloadPlugin({
index: 'preload.html',
extensions: ['woff2'],
filter: /(materialicons)/i,
replaceCallback: ({ indexSource, linksAsString }) => {
return indexSource.replace('{{{preloadLinks}}}', linksAsString);
},
}),
]
});
exports.expose = () => ({
module: {
rules: [
{
test: require.resolve('jquery'),
loader: 'expose-loader',
options: {
exposes: {
globalName: [
'$',
'jQuery',
],
},
},
},
],
},
});

View File

@@ -0,0 +1,24 @@
const { ESBuildMinifyPlugin } = require('esbuild-loader');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { cleanDistFolders } = require('./webpack.parts');
const { merge } = require('webpack-merge');
exports.productionConfig = () => (
merge(
{
devtool: 'hidden-source-map',
optimization: {
minimize: true,
minimizer: [
new ESBuildMinifyPlugin({
target: 'es2015',
format: 'iife'
}),
new CssMinimizerPlugin()
],
},
},
cleanDistFolders()
)
);

View File

@@ -0,0 +1,5 @@
const cssjanus = require('cssjanus');
module.exports = function (source) {
return cssjanus.transform(source);
}

View File

@@ -0,0 +1,67 @@
const fs = require('fs');
const path = require('path');
const themeDev = path.resolve(__dirname, '../src');
const envFilePath = './webpack/.env';
if (fs.existsSync(envFilePath)) {
require('dotenv').config({path: envFilePath});
}
const {
PORT: port = null,
PUBLIC_PATH: publicPath = null,
SERVER_ADDRESS: serverAddress = null,
SITE_URL: siteURL = null,
} = process.env;
const entriesArray = {
theme: ['scss', 'ts'],
error: ['scss'],
theme_rtl: ['scss'],
error_rtl: ['scss'],
rtl: ['scss'],
};
exports.webpackVars = {
themeDev,
publicPath,
serverAddress,
siteURL,
port,
entriesArray,
getEntry: (entries) => {
const resultEntries = {};
for (const entry in entries) {
const files = [];
if (!entries.hasOwnProperty(entry)) {
continue;
}
for (const ext in entries[entry]) {
const extension = entries[entry][ext];
files.push(path.resolve(themeDev, `./${extension === 'ts' ? 'js' : extension}/${entry}.${extension}`));
}
resultEntries[entry] = files;
}
return resultEntries;
},
getOutput: ({
mode, publicPath, siteURL, port, serverAddress,
}) => ({
filename: 'js/[name].js',
chunkFilename: mode === 'production' ? 'js/[chunkhash].js' : 'js/[id].js',
path: path.resolve(themeDev, '../assets'),
publicPath: mode === 'production' ? '../' : `${serverAddress === 'localhost' ? siteURL : `${siteURL}:${port}`}${publicPath}`,
pathinfo: false,
library: {
name: 'Theme',
type: 'window',
}
}),
};