@iamota/iamota-webpack
Version:
Helper tools for Webpack for iamota Framework (WordPress and Shopify)
164 lines (142 loc) • 5.32 kB
JavaScript
// ----------------------------------------------------------------------------
// Webpack Shopify Config
// ----------------------------------------------------------------------------
//
// Webpack configuration for processing Shopify projects and syncing via ThemeKit
//
// ----------------------------------------------------------------------------
/**
* Load Dependencies
*/
const { merge } = require('webpack-merge');
const CopyPlugin = require('copy-webpack-plugin');
const colors = require('picocolors');
const fs = require('fs');
const path = require('path');
/**
* Initialize Config
*/
let config = {};
exports.init = function (config) {
this.config = config;
// ThemeKit Defaults
this.config.themeKitFlags = {
env: this.config.env.target,
};
return this;
};
/**
* Process Shopify Tasks
*/
exports.process = function () {
return merge([
this.copyShopifyCode(),
this.showCompilerStatus(),
]);
};
// Helper to determine which .shopifyignore file to use based on target
exports.getShopifyIgnore = function() {
const baseIgnore = '.shopifyignore';
const fallbackTarget = 'dev';
if (this.config?.env?.target) {
let target = this.config.env.target;
if (target === 'localhost') target = 'local';
if (target === 'production') target = 'prod';
// Check for a specific .shopifyignore.<target> file
const candidate = `${baseIgnore}.${target.replace(/\//g, '_')}`;
const candidatePath = path.resolve(candidate);
if (fs.existsSync(candidatePath)) {
return candidate;
}
// For 'local' and 'prod', just use the base .shopifyignore as fallback
if (['local', 'prod'].includes(target)) {
return baseIgnore;
}
// For other targets, check for a .shopifyignore.dev fallback first
const fallbackPath = path.resolve(`${baseIgnore}.${fallbackTarget}`);
if (fs.existsSync(fallbackPath)) {
return `${baseIgnore}.${fallbackTarget}`;
}
}
// Default to the base .shopifyignore file if not other matches found
return baseIgnore;
}
/**
* Copy Shopify Code from "src" to "dist" (and flatten directory structures)
*/
exports.copyShopifyCode = function () {
return {
plugins: [
// Copy Liquid Files
new CopyPlugin({
patterns: [
{
from: 'src/config/*',
to: 'config/[name][ext]',
},
{
from: 'src/locales/**/*.json',
to: 'locales/[name][ext]',
},
{
from: 'src/templates/**/*.(liquid|json)',
to: 'templates/[name][ext]',
globOptions: {
// Ignore customer account templates (handled below)
ignore: ['**/templates/customers/**'],
},
},
{
from: 'src/templates/customers/**/*.(liquid|json)',
to: 'templates/customers/[name][ext]',
},
{
from: 'src/layout/**/*.liquid',
to: 'layout/[name][ext]',
},
{
from: 'src/sections/**/*.liquid',
to: 'sections/[name][ext]',
},
{
from: 'src/snippets/**/*.liquid',
to: 'snippets/[name][ext]',
},
{
from: 'src/blocks/**/*.liquid',
to: 'blocks/[name][ext]',
noErrorOnMissing: true,
},
// Copy and rename the correct .shopifyignore file to dist root as .shopifyignore
{
from: this.getShopifyIgnore(),
to: '.shopifyignore',
noErrorOnMissing: true,
toType: 'file', // Ensure it's treated as a file, not a directory
},
]
}, {
copyUnmodified: true
}),
],
};
};
/**
* Initialize "ThemeKit Watch" after the initial build
*/
exports.showCompilerStatus = () => ({
plugins: [
{
apply: (compiler) => {
// A single asset has been emitted
compiler.hooks.assetEmitted.tap('iamotaShopifyPlugin', (file) => {
console.log(`📄 ${colors.cyan(file)} successfully processed`);
});
// All assets queued have been emitted
compiler.hooks.afterEmit.tap('iamotaShopifyPlugin', () => {
console.log(`🚀 ${colors.magentaBright('Webpack successfully processed all assets')}`);
});
}
}
]
});