How to Override .js File in Magento PWA Studio

pwapwa-studio

I installed pwa my local directory. but I want to override js my component in the src directory. so please anyone help me?

Best Answer

I understand your issue with the PWA override js file into your component for that you have to add "moduleOverrideWebpackPlugin.js" this file into your root directory src/

And add below code into the file

const path = require('path');
const glob = require('glob');

module.exports = class NormalModuleOverridePlugin {
constructor(moduleOverrideMap) {
    this.name = 'NormalModuleOverridePlugin';
    this.moduleOverrideMap = moduleOverrideMap;
}

requireResolveIfCan(id, options = undefined) {
    try {
        return require.resolve(id, options);
    } catch (e) {
        return undefined;
    }
}
resolveModulePath(context, request) {
    const filePathWithoutExtension = path.resolve(context, request);
    const files = glob.sync(`${filePathWithoutExtension}@(|.*)`);
    if (files.length === 0) {
        throw new Error(`There is no file '${filePathWithoutExtension}'`);
    }
    if (files.length > 1) {
        throw new Error(
            `There is more than one file '${filePathWithoutExtension}'`
        );
    }

    return require.resolve(files[0]);
}

resolveModuleOverrideMap(context, map) {
    return Object.keys(map).reduce(
        (result, x) => ({
            ...result,
            [require.resolve(x)]:
            this.requireResolveIfCan(map[x]) ||
            this.resolveModulePath(context, map[x]),
        }),
        {}
    );
}

apply(compiler) {
    if (Object.keys(this.moduleOverrideMap).length === 0) {
        return;
    }

    const moduleMap = this.resolveModuleOverrideMap(
        compiler.context,
        this.moduleOverrideMap
    );

    compiler.hooks.normalModuleFactory.tap(this.name, (nmf) => {
        nmf.hooks.beforeResolve.tap(this.name, (resolve) => {
            if (!resolve) {
                return;
            }

            const moduleToReplace = this.requireResolveIfCan(resolve.request, {
                paths: [resolve.context],
            });
            if (moduleToReplace && moduleMap[moduleToReplace]) {
                resolve.request = moduleMap[moduleToReplace];
            }

            return resolve;
        });
    });
}
};

Use the code in this file as per your requirements.

Now add code into the "local-intercept.js" file located into the src/targets/ and add below code into this file

const moduleOverridePlugin = require('../moduleOverrideWebpackPlugin');
const { Targetables } = require('@magento/pwa-buildpack');
const componentOverrideFooter = module.exports={
    ['@magento/venia-ui/lib/components/Footer']:'src/components/Footer'
};

module.exports = targets => {
   targets.of("@magento/venia-ui").routes.tap(routes => {
    routes.push({
        name: "HelloworldCustomRouter",
        pattern: "/helloworlds",
        path: require.resolve("../components/Helloworld/helloworld.js")
    });
    return routes;
});

targets.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => {
    new moduleOverridePlugin(componentOverrideFooter).apply(compiler);
});

const targetables = Targetables.using(targets);
};

Now if you want to override the footer component then create a footer directory in the component directory and add footer.js and index.js files to this component

After copying the file @magento/venia-ui/lib/components/Footer/footer.js to /src/lib/components/Footer/footer.js, edit the footer.js file and replace the import paths with the relevant package, so it points to the correct import path of the core component. For example,

// import Logo from '../Logo';
import Logo from '@magento/venia-ui/lib/components/Logo';
// import Newsletter from '../Newsletter';
import Newsletter from '@magento/venia-ui/lib/components/Newsletter';
// import { useStyle } from '../../classify';
import { useStyle } from '@magento/venia-ui/lib/classify';
// import defaultClasses from './footer.module.css';
import defaultClasses from '@magento/venia- 
ui/lib/components/Footer/footer.module.css';
// import { DEFAULT_LINKS, LOREM_IPSUM } from './sampleData';
import { DEFAULT_LINKS, LOREM_IPSUM } from '@magento/venia- 
ui/lib/components/Footer/sampleData';

Create a src/components/Footer/index.js file with the following content to set the default component export for the Footer directory.

export { default } from "./footer";

For more information you can refer the magento official document guide https://developer.adobe.com/commerce/pwa-studio/tutorials/basic-modifications/modify-footer/

Related Topic