Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to resolve specifier 'date-fns/format' Angular 18 #705

Open
vahidsamimi opened this issue Dec 4, 2024 · 3 comments
Open

Unable to resolve specifier 'date-fns/format' Angular 18 #705

vahidsamimi opened this issue Dec 4, 2024 · 3 comments

Comments

@vahidsamimi
Copy link

vahidsamimi commented Dec 4, 2024

I added the following two packages as dependencies in the package.json file

"date-fns": "^4.1.0",
"date-fns-tz": "^3.2.0",

However, when I run the remote app that uses these packages, I encounter the error

Unable to resolve specifier 'date-fns/format'

image

Below is the code where I define the DateHelperService, which I import into the remote app.

import { Injectable } from '@angular/core';
import { format, formatISO, isValid, parseISO } from 'date-fns';

@Injectable({
  providedIn: 'root',
})
export class DateHelperService {
  render(dateString: string, pattern: string): string {
    const date: Date = parseISO(dateString);
    return isValid(date) ? format(date, pattern) : '';
  }

  renderDate(date: string): string {
    return this.render(date, 'dd.MM.yyyy');
  }

  renderDateTime(backendDateTime: string): string {
    if (!this.isValidBackendDateTimeString(backendDateTime)) return '';
    const date = backendDateTime.split('T')[0];
    const time = backendDateTime.split('T')[1];
    return this.renderDate(date) + ' ' + time;
  }

  renderTimestamp(dateString: string): string {
    return this.render(dateString, 'dd.MM.yyyy HH:mm:ss');
  }

  renderShortenedTimestamp(dateString: string): string {
    return this.render(dateString, 'dd.MM. HH:mm');
  }

  toBackEndDateTime(date: Date, fallback?: string): string {
    return isValid(date) ? formatISO(date).split('+')[0] : fallback || '';
  }

  toBackEndDate(date: Date, fallback?: string): string {
    return isValid(date) ? format(date, 'yyyy-MM-dd') : fallback || '';
  }

  getTime(date: Date, fallback?: string): string {
    return isValid(date) ? format(date, 'HH:mm') : fallback || '';
  }

  isValidBackendDateTimeString(dateString = ''): boolean {
    // Regular expression to match the format YYYY-MM-DDTHH:MM:SS
    // which is expected by BE
    const regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/;
    return regex.test(dateString);
  }
}

and here is federation.config.js

const { withNativeFederation, share, shareAll } = require('@angular-architects/native-federation/config');

module.exports = withNativeFederation({

  name: 'remote',

  exposes: {
    './routes': './projects/management.routes.ts',
  },

  shared: {
    'date-fns': {
    singleton: true,
    strictVersion: false,
    requiredVersion: '^4.1.0', 
  },
    ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
    ...share(
      [
        '@angular/common/locales/de',
        '@angular/common/locales/extra/de',
      ].reduce(
        (acc, name) => ({
          ...acc,
          [name]: { singleton: true, strictVersion: true, requiredVersion: 'auto', includeSecondaries: false },
        }),
        {},
      ),
    ),
  },

  skip: [
    'rxjs/ajax',
    'rxjs/fetch',
    'rxjs/testing',
    'rxjs/webSocket',
  ],
  sharedMappings: ['@insure-iwp/shared' , '@insure-iwp/intent-management'],

});

@manfredsteyer
Copy link
Contributor

Hi,

do you use the latest version of NF?
Can you please provide a reproduction?

@ToraTengu
Copy link

We're having the same issue with the lib chart.js.

I think it's the same problem: both packages use the CommonJS export format and don't seem to have any ESM support.

@ToraTengu
Copy link

Hello @manfredsteyer ,

I think I have found the issue regarding both packages: secondary entrypoint in the packages being imported from a third-party lib.

Both packages, beside the main module, exposes multiple submodules for ease of use, for instance :
chart.js/auto - for automatic full import of everything in charts.js;
data-fns/format - for direct access to the format function (data-fns seems to expose all it functions this way).

The workaround is to duplicate the sharing of the lib (one for the main module via the NF plugin and another for the problematic(s) submodule(s) manually).

shared: {
    "chart.js/auto": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    "date-fns/format": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
},

I don't know if that is enough for you or if you will want to add some logic to the NF plugin to take these secondary entrypoints into account...

@vahidsamimi, the offending piece of code is not in the service that you posted but in a function from the date-fns-tz package that your using in your codebase.

The function (most likely culprit is formatInTimeZone, look around for the imports from date-fns-tz) is importing the format function from date-fns via the secondary entrypoint (in my case it was the PrimeNG chart component that imports charts.js/auto).

Hope this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants