Angular - internationalization (i18n) - javascript

What is the best way to implement the internationalization for a angular application at the moment?

The official i18n angular2 will be implemented in one of the rc release before the final release. It also will be more advanced than the current solutions.
More info how the new concept of i18n works in angular2:
https://lingohub.com/blog/2015/03/angular-2-i18n-update-ng-conf-2015
UPDATE 6 SEPTEMBER 2016:
Support for i18n is now official in Angular 2 RC6
Official release blog:
https://angularjs.blogspot.nl/2016/09/angular-2-rc6_1.html
A sample of internationalization with Angular 2 RC6
https://github.com/StephenFluin/i18n-sample

At the moment the best alternative is is to use ng2-translate, which is a port to Angular 2 of the well known ng-translate. This will likelly cover the majority of use cases.
Later for Angular 2 there will be an official i18n implementation.

According to change log https://github.com/angular/angular/blob/master/CHANGELOG.md, a big piece of i18n was introduced in Angular 2 RC5:
i18n: merge translations 7a8ef1e
Unfortunately, I still don't observe any useful documentation.
However, according to https://github.com/angular/angular/issues/9104, the simple cases are already covered
{{ 'TRANSLATION_ID' | translate }}
Search this document https://docs.google.com/document/d/1mwyOFsAD-bPoXTk3Hthq0CAcGXCUw-BtTJMR4nGTY-0/edit for {{ 'TRANSLATION_ID' | translate }} for more details.

Recently I've created an in depth article about this...
Internationalization
Introduction
The Introduction of ngx-i18nsupport sums up the problem pretty well
Angular has a specific way of dealing with internationalization (i18n). It is described in the official documentation Angular Cookbook Internationalization (i18n).
Said in one sentence,
markup your strings to translate in your templates with an attribute i18n
run the Angular extraction tool (ng-xi18n) to extract the strings in an XML Format called [XLIFF-1.2]
copy and then translate the extracted file for every language you plan to support
run the ng compiler to generate a special version of your app for the different languages
But there are some maior gaps in the workflow. That´s where this tool comes into play.
First, you have to create a complete translation, otherwise, the ng compiler will not generate a version. It is not possible to run with partial translation.
Second, whenever you change something in your app, you have to regenerate the xliff, but there is no documented way how to merge this with the already existing translated files. There are new translation unit, that you have to merge in, and there are translation units, that do not exist any more.
We're going to use the ngx-i18nsupport-package to solve this issue.
Prepare Angular-App for i18n
Install Package #angular/localize using the angular-cli
ng add #angular/localize
Add the i18n-section to your angular.json in your project-section. Add the languages you need and change the source of your translations (the language you use as default in code/html) if required NOT RECOMMENDED STICK WITH EN IF EVER POSSIBLE.
Also make sure to set localize to true for your production-configuration.
{
...
"projects": {
"yourprojectname": {
"i18n": {
"sourceLocale": "en",
"locales": {
"de": "src/locale/messages.de.xlf",
"fr": "src/locale/messages.fr.xlf",
"it": "src/locale/messages.it.xlf"
}
},
...
"architect": {
"build": {
...
"configurations": {
"production": {
"localize": true,
...
Install ngx-i18nsupport
Run the following command to install ngx-i18nsupport
npm install -g ngx-i18nsupport
Configure xlf-merge
Add the following block the root-section of package.json and change it for your needs.
"xliffmergeOptions": {
"srcDir": "src/locale",
"languages": [
"de",
"fr",
"it"
],
"preserveOrder": true,
"beautifyOutput": true
}
languages
languages your app needs to support. Make sure it matches the i18n-definition your angular.json!
srcDir
output-dir for translation-files. Make sure it matches the i18n-definition your angular.json!
preserveOrder
Ensures the order of you translation isn't changed (not ordered to abc or whatever). This makes it easier to compare different version of the translation files.
beatifyOutput
formats xml nicely
Add some translations to your code
Make sure you have actual translations in your app like
<p i18n>Some random pagagraph that needs translation</p>
or
alert($localize `User ${username} doesn't exist!`);
Generate Translation Files
Run the following command to generate translation files. If you changed the --output-path make sure to change it accordingly.
ng extract-i18n --output-path src/locale
Call xliffmerge now to fix the issues mentioned in the introduction
xliffmerge
Recommendation Add this Command to the scrips section in your
package.json
"scripts": {
"translate": "ng extract-i18n --output-path src/locale && xliffmerge",
"xliffmerge": "xliffmerge",
...
You can run npm run translate any time you want to upate translations.
Test your app in a different language
You may want to test how your app looks translated for a specific language.
Add a build-configurations and serve-options to set the localize-language for each language used in your app.
HINT Don't forget to replace yourprojectname
angular.json
{
...
"projects": {
"yourprojectname": {
...
"architect": {
"build": {
...
"configurations": {
"de": {
"localize": ["de"]
},
"fr": {
"localize": ["fr"]
},
"it": {
"localize": ["it"]
}
...
}
},
"serve": {
...
"configurations": {
...
"development-de": {
"browserTarget": "yourprojectname:build:development,de"
},
"development-fr": {
"browserTarget": "yourprojectname:build:development,fr"
},
"development-it": {
"browserTarget": "yourprojectname:build:development,it"
}
Run your app in the desired language
ng serve -o --configuration=development-de
Recommendation Add a script starting your app in your apps supported langauges simultanialy each language on a different port
package.json
"scripts": {
"start": "ng serve -o",
"start-de": "ng serve -o --configuration=development-de --port=4201",
"start-fr": "ng serve -o --configuration=development-fr --port=4202",
"start-it": "ng serve -o --configuration=development-it --port=4203",
...
Now you can run your app simultaneously in any language you like
npm run start-de.
Have Fun!
😄

Related

How to create multiple pages with different languages from one template?

I want to generate multiple pages which will have content on different languages from one common template. How can I do it with webpack?
I tried to use different webpack plugins like webpack-static-i18n-html, i18n-webpack-plugin but nothing works for me. The best thing I found is a webpack-static-i18n-html, but it has bad support and this plugin can't watch changes in JSON files with translated text. Below is what I have for now.
This is my code from webpack.common.js.
const Path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const StaticI18nHtmlPlugin = require("webpack-static-i18n-html");
//...
module.exports = {
//...
plugins: [
//...
new StaticI18nHtmlPlugin({
locale: 'en',
locales: ['en', 'ua', 'ru'],
baseDir: Path.posix.join(__dirname, ".."),
outputDir: 'src/localized-pages',
outputDefault: '__lng__/__file__',
localesPath: 'src/locales',
files: 'src/templates/index.html'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: Path.resolve(__dirname, '../src/templates/index.html')
}),
new HtmlWebpackPlugin({
filename: 'ua/index.html',
template: Path.resolve(__dirname, '../src/localized-pages/ua/src/templates/index.html')
}),
new HtmlWebpackPlugin({
filename: 'ru/index.html',
template: Path.resolve(__dirname, '../src/localized-pages/ru/src/templates/index.html')
}),
//...
],
//...
};
I also have webpack.dev.js and webpack.prod.js which I merge with webpack.common.js via webpack-merge plugin. As you can see, after generating pages, I have to use HtmlWebpackPlugin to serve them. It's awkward to use.
locales folder:
locales
|-en.json
|-ua.json
|-ru.json
en.json file:
{
"key": {
"innerKey" : "value"
}
}
Then plugin generates from:
<p data-t>key.innerKay</p>
this
<p>value</p>
But as I said, If I change en.json nothing will regenerate. I will not use this way to generate multiple pages for different languages.
So, I would like to generate several pages from one template. Is there any way to do this with webpack?
I was working on a multi language admin dashboard with Webpack and was wondering how could I tackle this problem until I found a way to make everything automatic with a multiple language web template.
First of all, webpack-static-i18n-html isn't a good solution because most of its packages are deprecated. But actually the mentioned package is based on a good npm package called node-static-i18n. So, the first thing you need to do is installing this npm package using this command
npm install -g static-i18n
Next, you need to make your translation file as *.json files and in json format and put them in a folder which I named "locales" and I put it in my "src" folder of my project. I need two languages for my website. One of them is English and another is Farsi or Persian. Therefore I made two file namely fa.json and en.json. So, I have folder and file structure like the picture below:
My file and folder structure in my Webpack project
This is part of my en.json file as an example:
{
"menu": {
"items": {
"dashboard": "Dashboard",
"posts": "Posts",
"media": "Media"
},
"sub": {
"items": {
"all-posts": "All Posts",
"add-new-post": "Add New",
"categories": "Categories"
}
}
}
}
This is part of my fa.json file as an example:
{
"menu": {
"items": {
"dashboard": "پیشخوان",
"posts": "نوشته ها",
"media": "رسانه"
},
"sub": {
"items": {
"all-posts": "نوشته ها",
"add-new-post": "افزودن نوشته",
"categories": "دسته ها"
}
}
}
}
and you can use them in your html tags like this:
<span class="className" data-t>menu.items.dashboard</span>
Please notice that for using translation you should use the attribute data-t in your tags like span then you can use key and values saved in your related json file to use translations between your tags. for more information about data-t and its usage please go to the plugin's Github page that I mentioned it earlier in this text on the plugin name.
Next, you should write needed command in the script section of your package.json file to run node-static-i18n to translate your template based on your html template file and save them in i18n folder in root of your project as below:
"scripts": {
"i18n": "static-i18n -l en -i fa -i en src --localesPath src/locales/",
}
in the above command:
-l: The default locale.
-i: the list of locales to be generated.
--localesPath: The directory of the translations, where each file should be named LOCALE_NAME.json
Now if you run npm run i18n this command should make a folder in root path of your project called i18n containing html files in two languages in this case. it will be like the picture below:
i18n folder and translated html files in it
Next you should config your Html Webpack Plugin in your Webpack config file to show these pages in your browser like this:
plugins: [
.
.
.
new HtmlWebpackPlugin({
//inject: false,
chunks: ['main'],
template: 'i18n/index.html',
filename: 'index.html'
}),
new HtmlWebpackPlugin({
//inject: false,
chunks: ['main-rtl'],
template: 'i18n/fa/index.html',
filename: 'fa/index.html'
})
]
because you need to see changes on your browser automatically you need another package called npm-watch to install through this command:
npm install -D npm-watch
Then, you should change script section of your package.json like this:
"scripts": {
"i18n-watch": "watch 'npm run i18n' src",
"i18n": "static-i18n -l en -i fa -i en src --localesPath src/locales/",
}
By using the command npm run i18n-watch whenever you make any changes in your locale files or your original html template in src folder it's gonna re-translate your html file based on new information and if you're running your webpack dev server you can see the result right after you save changes.
After that, to run i18n-watch command and your Webpack dev server at the same time it would be great installing another npm package for this purpose called npm-run-all by using the command below:
npm i -D npm-run-all
Finally, you can change the script section of your package.json like this to run i18n-watch and your Webpack dev server at the same time and after that if you make any changes you can see the result in the browser right after saving changes.
"scripts": {
"i18n-watch": "watch 'npm run i18n' src",
"i18n": "static-i18n -l en -i fa -i en src --localesPath src/locales/",
"webpack-dev": "webpack-dev-server --open --config=config/webpack.dev.js",
"start": "npm-run-all --parallel webpack-dev i18n-watch"
}
Now, if you use npm start in your terminal you will see your Webpack dev server and i18n-watch are running at the same time watching for any changes.
Hopefully this makes sense.

Module not found: Error: Can't resolve 'crypto'

I am getting the following list of errors when I run ng serve.
My package JSON is as follows:
{ "name": "ProName", "version": "0.0.0", "scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e" }, "private": true, "dependencies": {
"#angular-devkit/build-angular": "~0.12.0",
"#angular/animations": "5.2.10",
"#angular/common": "5.2.10",
"#angular/compiler": "5.2.10",
"#angular/compiler-cli": "5.2.10",
"#angular/core": "5.2.10",
"#angular/forms": "5.2.10",
"#angular/platform-browser": "5.2.10",
"#angular/platform-browser-dynamic": "5.2.10",
"#angular/router": "5.2.10",
"#types/dotenv": "^4.0.3",
"#types/errorhandler": "0.0.32",
"#types/express": "^4.16.0",
"#types/node": "^10.5.1",
"apostille-library": "^7.1.0",
"core-js": "^2.5.4",
"dotenv": "^6.0.0",
"errorhandler": "^1.5.0",
"express": "^4.16.0",
"nem2-sdk": "^0.9.7",
"rxjs": "~6.3.3",
"stream": "0.0.2",
"tslib": "^1.9.0",
"typescript": "^2.9.2",
"zone.js": "~0.8.26" } }
The error I get :
ERROR in ./node_modules/aws-sign2/index.js Module not found: Error:
Can't resolve 'crypto' in
'/Users/MYPC/Documents/Myproj/ProName/node_modules/aws-sign2' ERROR in
./node_modules/aws4/aws4.js Module not found: Error: Can't resolve
'crypto' in '/Users/MYPC/Documents/Myproj/ProName/node_modules/aws4'
ERROR in ./node_modules/ecc-jsbn/index.js Module not found: Error:
Can't resolve 'crypto' in
'/Users/MYPC/Documents/Myproj/ProName/node_modules/ecc-jsbn' ERROR in
./node_modules/http-signature/lib/verify.js Module not found: Error:
Can't resolve 'crypto' in
'/Users/MYPC/Documents/Myproj/ProName/node_modules/http-signature/lib'
ERROR in ./node_modules/http-signature/lib/signer.js Module not found:
Error: Can't resolve 'crypto' in
'/Users/MYPC/Documents/Myproj/ProName/node_modules/http-signature/lib'
ERROR in ./node_modules/nem-sdk/build/external/nacl-fast.js Module not
found: Error: Can't resolve 'crypto' in
'/Users/MYPC/Documents/Myproj/ProName/node_modules/nem-sdk/build/external'
ERROR in ./node_modules/nem-sdk/node_modules/aws-sign2/index.js
I ran into a similar issue lately while trying to use another library (tiff.js) in a small project I was experimenting with.
The way I got around this was to add the following to my package.json file, right after the devDependencies section.
"devDependencies": {
...
},
"browser": {
"crypto": false
}
This didn't seem to have any adverse effect when trying to use the library in the application.
Adding this setting in tsconfig.json file under that project resolve this warning
"compilerOptions": {
"baseUrl": "./",
"paths": {
"crypto": [
"node_modules/crypto-js"
]
}
I like R. Richards's answer, but I thought it would be useful to provide some more information.
This is a known issue with Angular, and the Angular CLI dev team seems to think it's a feature rather than a bug. I, as well as other developers in this issue thread, disagree. Contributors to that thread provided several workaround fixes, but my project didn't compile successfully until I implemented R. Richards' solution. I didn't revert the previous changes, though, so tacnoman's and GrandSchtroumpf's fixes may be of use to others.
Some, like clovis1122 here and others in that issue thread, have questioned why a web app would need access to these libraries and why the necessary tasks can't be completed on the server side instead. I can't speak for everyone, but my use case is that, when authenticating a user account, Strapi responds with a JSON Web Token string that must be decoded by the client. Since the necessary library depends on crypto and stream, you won't be able to extract the JWT expiration time unless those dependencies are available.
In case anyone has trouble extrapolating from R. Richards' answer, you'll have to set to false any dependencies that are showing up in "can't resolve x" errors. For example, the critical part of my package.json is:
"browser": {
"crypto": false,
"stream": false
}
I thought I would expand on what Tarique Ahmed wrote in his answer.
I was using an npm module that had the following line in the code:
const crypto = require('crypto');
I couldn't add:
"browser": {
"crypto": false
}
to the package.json because the crypto package had to be part of the build.
It turns out that during the compilation process Angular seems to have decided to install the crypto-browserify package instead of crypto.
Adding the following to the tsconfig.json file instructs the build to use the crypto-browserify library every time that crypto is required. As you can see, I had the same issue for the stream package.
"paths": {
"crypto": [
"node_modules/crypto-browserify"
],
"stream": [
"node_modules/stream-browserify"
]
}
After having the same issue with Angular 11 and crypto-js 4 (and manually setting the path in tsconfig.json), I found rolling back crypto-js to version 3.1.9-1 fixed the issue. It seems a change made in version 4 caused the issue.
npm install crypto-js#3.1.9-1
Explained here in repo issues:
GitHub issue
If you upgraded to Webpack 5, you need to add this to your webpack config file:
resolve: {
fallback: { crypto: false },
},
aws-sign2 is a NodeJS package (and crypto is a NodeJS module), but it looks like you're dealing with a web application. It makes sense that the crypto module is not available in that environment.
Would it be possible to complete what you need to do server-side? Otherwise, you may need to look for another package.
For Laravel Inertia JS project, my solution was:
1- Add dependencies to package.json
"dependencies": {
"crypto-browserify": "3.12.0",
"crypto-random-string": "^3.3.0",
"stream": "^0.0.2"
}
2-In webpack.config.js:
const path = require('path');
module.exports = {
resolve: {
alias: {
'#': path.resolve('resources/js'),
},
fallback: {
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream'),
},
},
};
3-Install, build and run:
npm install && npm run watch
I have resolved my issue using below steps:
Add below to tsconfig.json to resolve crypto warning:
"paths": {
"crypto": [
"node_modules/crypto-js"
]
},
and add below to angular.json
"options": {
"allowedCommonJsDependencies": [
"crypto-js"
],
...
}
My Error
In my Case the import { get } from "express/lib/response" is the culprit, which is automatically added by vs-code.
So, after removing it I solved my issue
When using #Laravel framework with Laravel Mix this is going to be more trick. I spend some hours on this NPM nightmare and found a solid solution.
So, in your webpack.mix.js you find the 'comment'
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
Now just below that comment add the following lines;
mix.webpackConfig(webpack => {
return {
plugins: [
new webpack.LoaderOptionsPlugin({
exports: {
resolve: {
fallback: {
crypto: require.resolve('crypto-browserify'),
}
}
}
})
]
};
});
Now you can use Laravel Mix just like you would edit webpack.config.js ;)
Also; In package.json remove:
--no-progress --hide-modules
These are no longer valid for WebPack >= 5. Enjoy!
After a deep a research i found that the solution is very simple: replace
import * as CryptoJS from 'crypto-js'; with declare var CryptoJS;
Using direct import may not work with ES6 Enviornment..
This may help you.
$ npm i crypto-js#latest // For using latest version 4
import AES from 'crypto-js/aes';
import Utf8 from 'crypto-js/enc-utf8';
import { secretKey } from './environments/environment';
/** Encryption */
const data = {key: 'Test Value'};
const ciphertext = AES.encrypt(JSON.stringify(data), secretKey).toString();
console.log('Encrypted Data', ciphertext);
/** Decryption */
const bytes = AES.decrypt(ciphertext, secretKey);
const decryptedData = JSON.parse(bytes.toString(Utf8));
console.log('Decrypted Data', decryptedData);
https://github.com/brix/crypto-js/issues/168#issuecomment-785617218
Add the option allowedCommonJsDependencies with literal "crypto-js" in a array, this in file angular.json:
"architect":
"build": {
"options": {
"allowedCommonJsDependencies": [
"crypto-js"
]
},
}
}
This will disable all warnings, tested in Angular 11.
My problem was that I was trying to build to node and web using the same code, but is not possible to built to web while importing a WebSocket dependency, ws in my case
So the solution is by using a wrapper:
Install a wrapper, I will use isomorphic-ws because is made for ws
npm i --save isomorphic-ws
Remove const WebSocket = require('ws')
Replace with:
const WebSocket = require('isomorphic-ws')
I ended up going into
node_modules/react-scripts/config/webpack.config.js
and adding:
fallback: {
// Here paste
crypto: require.resolve("crypto-browserify"),
https: require.resolve("https-browserify"),
http: require.resolve("stream-http"),
url : require.resolve("url")
}
And now my react app builds with errors but no dependency issues. Ill update this when I get it building.
Add
npm install crypto-js
Or Add a specific version according to your project need
npm install crypto-js#4.0.0
Also, run the above commands in Window "run as administrator" or in Linux use sudo
Alot of answers already but still none of them works. In my case I see warning message
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }' - install 'crypto-browserify' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "crypto": false }
comment from #stewii did helped me to resolved this.
There is now an ES modules version called "crypto-es". It clears these warnings. npmjs.com/package/crypto-es
After this I imported cryptoES
import CryptoES from 'crypto-es';
and remove the existing import of cryptoJs. Re-start the compile and Voila.. The warning message is gone.
I tried a lot of the solutions above but the final thing that worked for me was downloading the crypto-es package and adding, "type":"module" to package.json.
https://www.npmjs.com/package/crypto-es
I was facing same issue, Just run node patch.js and it worked. The issue is, browser doesn't allow server files to be run on browser. In case you need some of these, You can use node patch.js. If you don't want to run any server file on browser, you can simply apply above mentioned solution by #R.Richards. Might be helpful for someone..
In my case, the solution described by R.Richards doesn't work.
However, following several threads along this issue, I finally understood where to insert the recommendation provided in the warning message and solved this warning.
WARNING in ./node_modules/bcryptjs/dist/bcrypt.js 64:13-45
Module not found: Error: Can't resolve 'crypto' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\bcryptjs\dist'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
**If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "crypto": false }**
Differently from many contributors, I didn't want to install crypto-browserify as I don't need it (*), and I chose to add the fallback { "crypto": false }.
However I didn't know where to add this fallback. After reading several threads, I found it was in the webpack.config.js file, which is located in the directory node_modules/react_scripts/config.
Adding this fallback made the compilation succeed without any warning.
(*) PS : I once tried to add the following fallback { "crypto": require.resolve("crypto-browserify") }, but it led to generation of 7 errors, requiring other modules :
Failed to compile.
Module not found: Error: Can't resolve 'stream' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\cipher-base'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "stream": false }
ERROR in ./node_modules/cipher-base/index.js 2:16-43
Module not found: Error: Can't resolve 'stream' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\cipher-base'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "stream": false }
ERROR in ./node_modules/readable-stream/lib/_stream_readable.js 43:13-37
Module not found: Error: Can't resolve 'buffer' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\readable-stream\lib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "buffer": false }
ERROR in ./node_modules/readable-stream/lib/_stream_writable.js 65:13-37
Module not found: Error: Can't resolve 'buffer' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\readable-stream\lib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "buffer": false }
ERROR in ./node_modules/readable-stream/lib/internal/streams/buffer_list.js 63:15-32
Module not found: Error: Can't resolve 'buffer' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\readable-stream\lib\internal\streams'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "buffer": false }
ERROR in ./node_modules/ripemd160/index.js 3:13-37
Module not found: Error: Can't resolve 'buffer' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\ripemd160'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "buffer": false }
ERROR in ./node_modules/safe-buffer/index.js 3:13-30
Module not found: Error: Can't resolve 'buffer' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\safe-buffer'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "buffer": false }
ERROR in ./node_modules/safer-buffer/safer.js 5:13-30
Module not found: Error: Can't resolve 'buffer' in 'C:\PC\Documents\3 - Projet MAKAO\dev\RepoAlecol\node_modules\safer-buffer'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "buffer": false }
webpack compiled with 7 errors
I had this problem in ReactJS with create-react-app(facebook)
Solution:
First install the necessary packages "crypto-browserify"
Modify webpack.config.js in reactjs with create-react-app this file is inside:
node_modules/react-scripts/config/webpack.config.js
Search module.exports and inside this function there is a return:
module.exports = function (webpackEnv) {
...
return {
...
resolve: {
...
fallback: {
// Here paste
crypto: require.resolve("crypto-browserify"),
}
}
}
}
Note: Is possible you need other packages how "stream-browserify" the steps are same. This solution works, but when the webpack project starts it shows warnings
Pd: I am not native speaker English, but I hope understand me.

Angular Universal: "Project could not be found in workspace."

I'm trying to convert my existing Angular Project to work with Angular Universal (https://universal.angular.io/). I'm following this tutorial: https://github.com/angular/angular-cli/wiki/stories-universal-rendering. I'm stuck at the end of Step 3 (Building the Bundle). The name of my project is "fundercat". When I try to run:
ng run fundercat:server
I get the error:
Project 'dist/fundercat' could not be found in workspace.
Following the tutorial, I modified the following line in app.module.ts:
#NgModule({
imports: [
// Modified this line:
BrowserModule.withServerTransition({appId: 'fundercat'}),
And I added the following to angular.json:
{
"$schema": "./node_modules/#angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"fundercat": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"architect": {
...
// added this block:
"server": {
"builder": "#angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/fundercat",
"main": "src/main.server.ts",
"tsConfig": "src/tsconfig.server.json"
}
}
Any idea what I'm doing wrong?
Double check that fundercat is the name of your project by looking at what is listed as the name in your package.json file. If the name is something other than fundercat, you will have to use that name in the command in order to build the server. For example, if your project is actually named FunderCat then you need to run ng run FunderCat:server to run the server.
I ran into a similar issue when I tried to add angular universal to the angular-tour-of-heroes project. The way the documentation was worded made it seem like "my-project" was some kind of special angular cli command for running the server. It's not. "my-project" refers to the name of the project you're working on. So I had to run ng run angular-tour-of-heroes:server to run the server in the tutorial project instead of ng run my-project:server.

Webpack && npm, how can I create a script that can both be imported by another webpack project, or included as a script tag?

Let's say I'm using webpack 4 and have a project that looks like this:
/src/index.js
const Important = "Important Text"
export default Important
global.important = Important
I compile it using the following webpack confing:
output: {
libraryTarget: 'commonjs2',
},
module: {
rules: [
{ ...babelConfig }
]
}
And the package.json has:
{
...packageJsonContents
"name": "important-project",
"main": "./dist/main.js",
}
This will create the minified file /dist/main.js
I save that plugin to npm as testproject
Now I create another project, configure Webpack and npm install important-project.
In the /src/index.js:
import Important from 'important-project'
console.log(Important) //prints "Important Text"
This works, however my goal is for this to be a general use plugin and I want to also be able to include it as a script tag in other projects, however when I include it as a script tag, it complains that module is not defined.
<script src="node_modules/important-project/dist/main.js"></script>
What's the conventional approach here? Should I create two builds? One for in html, and another for in webpack?

pass variable to webpack to build different bundle

I am trying to build a different bundle based on an argument passed to webpack.
I have a create-react-app that I have ejected from and currently currently if I do npm run build it builds a bundle using webpack. As I have both an english and spanish version of the site I was hoping that I could pass an argument here. i.e. to build a Spanish version something like npm run build:es.
My webpack file currently just builds the English bundle. There is a separate process during the application to pull in translations, but during the building of the bundle it would be great if I could stipulate which language to build the bundle for.
Anyone have any ideas.
The relevant webpack code is below:
//default messages for translations
var defaultMessages = require('/translations/en.json');
//more webpack stuff......
{
test: /\.(js|jsx)$/,
loader: require.resolve('string-replace-loader'),
query: {
multiple: Object.keys(defaultMessages).map(key => ({
search: `__${key}__`,
replace: defaultMessages[key]
}))
}
},
Webpack can receive a --env argument, which is then passed to the webpack.config file. The key is to export a function returning the configuration from your webpack.config.js, not the raw configuration.
$ webpack --env=lang_es
And in webpack.config.js:
module.exports = function(env) {
if (env === 'lang_es') {
// ...
}
return {
module: {
// ...
},
entry: {
// ...
}
}
}
And in package.json:
"scripts": {
"build_es": "webpack --env=lang_es",
}
This was originally really meant to distinguish between build types, e.g. development or production, but it's just a string passed into the config file - you can give it any meaning you want.
As hinted in the comments, using environment variables is the second, webpack-independent, approach. You can set the environment variable directly in package.json's scripts section:
"scripts": {
"build_es": "BUILD_LANG=es webpack",
}
(Use cross-env to set the environment when developing on Windows).
And in webpack.config.js:
if (process.env.BUILD_LANG === 'es') {
// ...
}
This environment-based approach has been used in a few places already (for example Babel's BABEL_ENV variable), so I'd say that it has gathered enough mileage to consider it proven and tested.
Edit: fixed the cross-env part to mention that it's only necessary on Windows.

Categories