angular-cli: webpack import(`@angular/common/locales/${mylocale}`) not working

Which @angular/* package(s) are the source of the bug?

common

Is this a regression?

Yes

Description

We load our locales dynamically using a dynamic import and registerLocaleData

this works in angular 12

const localeModule = await import(
  /* webpackInclude: /(sv|nb|da|fi|de|fr)/ */
  /* webpackChunkName: "locale" */
  `@angular/common/locales/${this.locale}.js`
)
registerLocaleData(localeModule.default)

The Problem

I found the root cause and it’s not a angular problem, but a webpack one https://github.com/webpack/webpack/issues/13865

But I though someone else might get stuck on the same thing, so I would add it as a regression.

Workaround

A workaround is to use a relative or absolute path to the node_modules folder instead

const localeModule = await import(
  /* webpackInclude: /(sv|nb|da|fi|de|fr).mjs$/ */
  /* webpackExports: "default" */
  /* webpackChunkName: "locale" */
  `node_modules/@angular/common/locales/${this.locale}`
)
registerLocaleData(localeModule.default)

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

Module not found: Error: Package path ./locales is not exported from package /myrepo/node_modules/@angular/common (see exports field in /myrepo/node_modules/@angular/common/package.json)

Please provide the environment you discovered this bug in

No response

Anything else?

No response

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 18
  • Comments: 15

Most upvoted comments

It’s important to point out that using Webpack specific features such as magic comments above are not supported by the Angular tooling team. The fact that the Angular CLI is using Webpack is an implementation detail which can change in the future.

This is because dynamic imports don’t work in Webpack when an exports with wildcard is specified in package.json

Example

  "exports": {
    "./locales/global/*": {
      "default": "./locales/global/*.js"
    },
    "./locales/*": {
      "default": "./locales/*.mjs"
    },

it seems that we blame a WebPack bug right? But why is it that these 2 that i also use:

import(numbro/languages/${localeId}). import(@uppy/locales/lib/${localeId}.js)

are still working like a charm? no need to change any code for that?

This approach worked for me: import('node_modules/@angular/common/locales/${this.locale}.mjs');

@adampasc, this issue is not caused by Angular, but rather it’s a Webpack bug.

Please see: https://github.com/webpack/webpack/issues/13865

This answer helped me highlightjs/highlight.js#3223 (comment)

this for me doesn’t work… if i do this:

        const module1 =  `@angular/common/locales/${localeId}.js`;
        import(module1).then(

then yes it compiles, but i got a warning: Warning: Critical dependency: the request of a dependency is an expression

and also the locale files are not generated (no output for the angular locales)

if i do this:

import(../../node_modules/@angular/common/locales/${localeId}.js)

which other say you now should do, that also doesn’t work because yes then the files are generated but the actual import at runtime doesn’t work…

image

as you can see the import askes for “./nl.js” but the map doesn’t have that there is a “./global/” in front of it. so it doesn’t map and can’t load it…

So how can i get this working? or is this just not possible right now and i need to postpone the angular 13 upgrade?