In a Nextjs project using next-i18next, I'm trying to read language json file from a cms but my configuration is not working.
This is my 'next-i18next.config.js':
const I18NextHttpBackend = require('i18next-http-backend/cjs');
module.exports = {
debug: process.env.NODE_ENV === 'development',
reloadOnPrerender: process.env.NODE_ENV === 'development',
i18n: {
defaultLocale: 'es',
locales: ['es'],
localeDetection: false,
},
ns: ['translation'],
defaultNS: 'translation',
react: {
useSuspense: true,
},
backend: {
loadPath: 'http://localhost:3001/locales/{{lng}}/{{ns}}.json',
requestOptions: {
cache: 'default',
credentials: 'same-origin',
mode: 'no-cors',
},
},
serializeConfig: false,
use: isBrowser ? [I18NextHttpBackend] : [],
}
I'm following the examples that I found in the official repository of the next-i18next and in the i18next-http-backend next example.
The endpoint has an object like:
{"title": "My title"}
This is the debug:
{
"debug": true,
"initImmediate": true,
"ns": [
"translation"
],
"defaultNS": "translation",
"fallbackLng": [
"es"
],
"fallbackNS": false,
"supportedLngs": false,
"nonExplicitSupportedLngs": false,
"load": "currentOnly",
"preload": false,
"simplifyPluralSuffix": true,
"keySeparator": ".",
"nsSeparator": ":",
"pluralSeparator": "_",
"contextSeparator": "_",
"partialBundledLanguages": false,
"saveMissing": false,
"updateMissing": false,
"saveMissingTo": "fallback",
"saveMissingPlurals": true,
"missingKeyHandler": false,
"missingInterpolationHandler": false,
"postProcess": false,
"postProcessPassResolved": false,
"returnNull": true,
"returnEmptyString": true,
"returnObjects": false,
"joinArrays": false,
"returnedObjectHandler": false,
"parseMissingKeyHandler": false,
"appendNamespaceToMissingKey": false,
"appendNamespaceToCIMode": false,
"interpolation": {
"escapeValue": false,
"prefix": "{{",
"suffix": "}}",
"formatSeparator": ",",
"unescapePrefix": "-",
"nestingPrefix": "$t(",
"nestingSuffix": ")",
"nestingOptionsSeparator": ",",
"maxReplaces": 1000,
"skipOnVariables": true
},
"errorStackTraceLimit": 0,
"localeExtension": "json",
"localePath": "./public/locales",
"localeStructure": "{{lng}}/{{ns}}",
"react": {
"useSuspense": true
},
"reloadOnPrerender": true,
"serializeConfig": false,
"use": [
null
],
"backend": {
"loadPath": "http://localhost:3001/locales/{{lng}}/{{ns}}.json",
"requestOptions": {
"cache": "default",
"credentials": "same-origin",
"mode": "no-cors"
},
"addPath": "/locales/add/{{lng}}/{{ns}}",
"allowMultiLoading": false,
"reloadInterval": false,
"customHeaders": {},
"queryStringParams": {},
"crossDomain": false,
"withCredentials": false,
"overrideMimeType": false
},
"lng": "es",
"defaultLocale": "es",
"locales": [
"es"
],
"localeDetection": false,
"resources": {
"es": {
"translation": {}
},
"en": {
"translation": {}
},
"ca": {
"translation": {}
}
},
"ignoreJSONStructure": true
}
Thanks.
If you want to use always your custom loadPath (client and server side), you need to do this:
module.exports = {
debug: process.env.NODE_ENV === 'development',
reloadOnPrerender: process.env.NODE_ENV === 'development',
i18n: {
defaultLocale: 'es',
locales: ['es', 'en'],
localeDetection: false,
},
ns: ['translation'],
defaultNS: 'translation',
react: {
useSuspense: true,
},
backend: {
loadPath: 'http://localhost:3000/api/{{ns}}/{{lng}}',
requestOptions: {
cache: 'default',
credentials: 'same-origin',
mode: 'no-cors',
}
},
serializeConfig: false,
use: [I18NextHttpBackend],
}
You need to also conditionally set the backend options:
module.exports = {
debug: process.env.NODE_ENV === 'development',
reloadOnPrerender: process.env.NODE_ENV === 'development',
i18n: {
defaultLocale: 'es',
locales: ['es', 'en'],
localeDetection: false,
},
ns: ['translation'],
defaultNS: 'translation',
backend: isBrowser ? {
loadPath: 'http://localhost:3000/locales/{{lng}}/{{ns}}.json',
requestOptions: {
cache: 'default',
credentials: 'same-origin',
mode: 'no-cors',
},
} : undefined,
serializeConfig: false,
use: isBrowser ? [I18NextHttpBackend] : [],
}
Related
Is it possible to get translations from cdn (s3 bucket)?
Config:
{
i18n: {
fallbackLng: 'en',
defaultLocale: 'empty',
locales: [
'empty',
'en',
'de',
'ee',
'es',
'fi',
'fr',
'gb',
'it',
'ko',
'lt',
'lv',
'nl',
'pl',
'pt',
'ru',
'sv',
'tr',
'zh',
],
localeDetection: false,
},
react: {
useSuspense: false,
},
serverLanguageDetection: true,
backend: {
loadPath: 'https://cdn-domain.com/{{ns}}/{{lng}}',
requestOptions: {
cache: 'default',
credentials: 'same-origin',
mode: 'no-cors',
},
},
reloadOnPrerender: true,
debug: true,
serializeConfig: false,
use: [I18NextHttpBackend],
};
Error
i18next::backendConnector: loading namespace translation for language en failed [Error: ENOENT: no such file or directory, open 'https://cdn-domain.com/translation/en'
I switched my NextJS app to SWC (I removed Babel`s config, and enabled the emotion plugin).
Now, I see that build time has increased from 80 s to ~200 s.
Does anyone have a similar experience?
My next.config.js:
// #ts-check
const path = require('path')
const _ = require('lodash')
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
const withImages = require('next-optimized-images')
const withFonts = require('next-fonts')
const withTM = require('next-transpile-modules')([
'#xxx/helpers',
'#xxx/ui',
'#xxx/api',
])
console.log('basePath -', process.env.BASE_PATH)
console.log(`Fs cache ${process.env.ENABLE_FS_CACHE ? 'enabled' : 'disabled'}`)
/**
* Filters out keys with undefined value to be compliant with Next's env type definition
* #param {{ [key: string]: string | undefined }} envs
* #returns {{ [key: string]: string}}
*/
const getEnvs = (envs) => {
/** #type {{ [key: string]: string}} */
const result = {}
Object.entries(envs).forEach(([key, env]) => {
if (env) result[key] = env
})
return result
}
/**
* #type {import('next').NextConfig}
*/
const settings = {
env: getEnvs({
...
}),
trailingSlash: true,
poweredByHeader: false,
basePath: process.env.BASE_PATH,
baseUrl: process.env.BASE_URL,
assetPrefix: process.env.ASSET_PREFIX,
esModule: true,
handleImages: ['jpeg', 'png', 'webp', 'gif'],
// #ts-ignore fix images config to match next types. We need to extract images sizes from test setup
images: {
disableStaticImages: true,
domains: ['images.ctfassets.net'],
loader: 'custom',
},
eslint: {
ignoreDuringBuilds: true,
},
experimental: {
emotion: true,
},
swcMinify: true,
distDir: 'dist',
webpack: (config, { isServer }) => {
config.module.rules.push({
test: /\.svg$/,
use: [
{
loader: '#svgr/webpack',
options: {
svgoConfig: {
plugins: [
{
name: 'removeViewBox',
active: false,
},
{ name: 'cleanupIDs', active: false },
{ name: 'prefixIds', active: true },
],
},
},
},
'url-loader',
],
})
config.module.rules.push({
test: /\.mp4$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/videos/`,
outputPath: `${config.isServer ? '../' : ''}static/videos/`,
name: '[name]-[hash].[ext]',
},
},
],
})
config.module.rules.push({
test: /\.json(.*?)\.data$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/data/`,
outputPath: `${config.isServer ? '../' : ''}static/data/`,
name: '[name]-[hash].json',
},
},
],
})
if (!isServer) {
config.resolve.fallback.fs = false
config.resolve.fallback.path = false
config.resolve.fallback.crypto = false
config.resolve.fallback.readline = false
}
return config
},
}
const enhanceConfig = _.flow([withImages, withFonts, withBundleAnalyzer, withTM])
module.exports = enhanceConfig(settings)
I encounter the following warning from redux toolkit.
However the error is not specificying where the non-seralizable actually is in my state.
My raw state from the redux dev tools looks like this. The warning occurs immededtly after starting the application.
user: {
ids: [
'61345318-2f7c-41ff-996c-4e537afcd5a1'
],
entities: {
'61345318-2f7c-41ff-996c-4e537afcd5a1': {
sub: '61345318-2f7c-41ff-996c-4e537afcd5a1',
email_verified: true,
name: 'Daniel Hallosdfsdf',
preferred_username: 'dani_1234',
email: 'sdfdsfdsfsdf#foo.com'
}
},
loggedInUser: '61345318-2f7c-41ff-996c-4e537afcd5a1',
isAuthenticated: true,
authenticationIsLoading: false,
loginIsLoading: false,
registerIsLoading: false,
deleteAccountAWSIsLoading: false,
resendSignUpLingIsLoading: false,
fullNameChangingIsLoading: false,
updateUsernameIsLoading: false,
sendCodeForMailUpdateIsLoading: false,
verifyEmailChangeCodeIsLoading: false,
passwordChangingIsLoading: false,
passwordForgottenMailIsSendLoading: false,
passwordChangingAfterPasswordForgottenIsLoading: false,
checkIfMailExistsIsLoading: false,
checkIfUsernameExistsIsLoading: false,
userSessionIsLoading: 'success',
userIsLoading: 'sucess',
getUpdatedSUYUHUserIsLoading: false,
getUpdatedAWSUserIsLoading: false
},
story: {
ids: [],
entities: {},
storyList: {
isLoading: 'idle',
count: '',
numberOfStories: '',
ids: []
},
storyListSideBarMap: {
isLoading: 'idle',
count: '',
numberOfStories: '',
ids: []
},
singleStory: {
isLoading: 'idle',
id: ''
},
updateStoryIsLoading: false,
postStoryIsLoading: false
},
place: {
ids: [],
entities: {},
placeList: {
count: '',
ids: []
},
placeSlider: {
isLoading: 'idle',
ids: []
},
placesOfStory: {
isLoading: 'idle'
},
placeBar: {
isLoading: 'idle',
id: ''
},
placesOnMap: {
isLoading: 'idle',
ids: []
},
selectedPlaceId: ''
},
profile: {
ids: [
'dani_1234'
],
entities: {
dani_1234: {
cognitoId: '61345318-2f7c-41ff-996c-4e537afcd5a1',
username: 'dani_1234',
bio: 'xcyvycxvxcvcxvcxv',
shortTitle: 'MUCsdfsdfdsfdsfng',
image: 'http://localhost:8000/media/profile_pics/Capture_1_5F75wR1.JPG',
storiesUrl: 'http://localhost:8000/api/v1/stories/?author=61345318-2f7c-41ff-996c-4e537afcd5a1',
placesUrl: 'http://localhost:8000/api/v1/places/?author=61345318-2f7c-41ff-996c-4e537afcd5a1',
storiesCount: 1,
placesCount: 1,
profileOwnerPermission: true
}
},
profileList: {
isLoading: 'idle',
count: '',
ids: []
},
profileListSideBar: {
isLoading: 'idle',
count: '',
ids: []
},
profileBar: {
isLoading: true,
id: ''
},
header: {
isLoading: 'failure',
id: 'dani_1234'
},
profilesOfStory: {
isLoading: 'idle'
},
updateProfileImageIsLoading: false,
updateDescriptionIsLoading: false,
deleteProfileImageIsLoading: false,
updateNicknameIsLoading: false
},
storyImage: {
ids: [],
entities: {},
storyImageList: {
isLoading: 'idle',
ids: []
},
addStoryImageIsLoading: false,
updateStoryImageIsLoading: false,
deleteStoryImageIsLoading: false
},
userInterface: {
ids: [],
entities: {},
profileEditIsOpen: false,
stepProfileEdit: 'EditProfile',
userAuthenticatesIsOpen: false,
stepUserAuthenticates: 'signIn',
browseMapOverlayIsOpen: false
}
}
I am happy for any clarification that helps me to find the non serializable value.
I am new to webpack and react, i downloaded one github project which suits my requirement and when i start my server, i see that css is not getting included in build html file.
'use strict';
const fs = require('fs');
const path = require('path');
const resolve = require('resolve');
const webpack = require('webpack');
const PnpWebpackPlugin = require('pnp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const getClientEnvironment = require('./env');
const paths = require('./paths');
const ManifestPlugin = require('webpack-manifest-plugin');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
const publicPath = '/';
const publicUrl = '';
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
// Check if TypeScript is setup
const useTypeScript = fs.existsSync(paths.appTsConfig);
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
],
},
},
];
if (preProcessor) {
loaders.push(require.resolve(preProcessor));
}
return loaders;
};
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
entry: [
require.resolve('react-dev-utils/webpackHotDevClient'),
paths.appIndexJs,
paths.appBuild + '/static/css/main.chunk.css',
],
output: {
pathinfo: true,
filename: 'static/js/bundle.js',
chunkFilename: 'static/js/[name].chunk.js',
publicPath: publicPath,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
},
optimization: {
splitChunks: {
chunks: 'all',
name: false,
},
runtimeChunk: true,
},
resolve: {
modules: ['node_modules'].concat(
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
'actions': path.resolve(__dirname, '../src/actions'),
'constants': path.resolve(__dirname, '../src/constants'),
'containers': path.resolve(__dirname, '../src/components/containers'),
'commons': path.resolve(__dirname, '../src/components/common'),
'reducers': path.resolve(__dirname, '../src/reducers'),
'domains': path.resolve(__dirname, '../src/domains'),
'libs': path.resolve(__dirname, '../src/libs')
},
plugins: [
PnpWebpackPlugin,
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
resolveLoader: {
plugins: [
PnpWebpackPlugin.moduleLoader(module),
],
},
module: {
strictExportPresence: true,
rules: [
{ parser: { requireEnsure: false } },
{
test: /\.(js|mjs|jsx)$/,
enforce: 'pre',
use: [
{
options: {
formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
{
oneOf: [
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '#svgr/webpack?-prettier,-svgo![path]',
},
},
},
],
],
cacheDirectory: true,
// Don't waste time on Gzipping the cache
cacheCompression: false,
},
},
{
test: /\.(js|mjs)$/,
exclude: /#babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
cacheCompression: false,
sourceMaps: false,
},
},
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
}),
},
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
}),
},
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders({ importLoaders: 2 }, 'sass-loader'),
},
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
},
'sass-loader'
),
},
{
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
loader: require.resolve('file-loader'),
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml
}),
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
new ModuleNotFoundPlugin(paths.appPath),
new webpack.DefinePlugin(env.stringified),
new webpack.HotModuleReplacementPlugin(),
new CaseSensitivePathsPlugin(),
new WatchMissingNodeModulesPlugin(paths.appNodeModules),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new ManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: publicPath,
}),
// TypeScript type checking
useTypeScript &&
new ForkTsCheckerWebpackPlugin({
typescript: resolve.sync('typescript', {
basedir: paths.appNodeModules,
}),
async: false,
checkSyntacticErrors: true,
tsconfig: paths.appTsConfig,
compilerOptions: {
module: 'esnext',
moduleResolution: 'node',
resolveJsonModule: true,
isolatedModules: true,
noEmit: true,
jsx: 'preserve',
},
reportFiles: [
'**',
'!**/*.json',
'!**/__tests__/**',
'!**/?(*.)(spec|test).*',
'!src/setupProxy.js',
'!src/setupTests.*',
],
watch: paths.appSrc,
silent: true,
formatter: typescriptFormatter,
}),
].filter(Boolean),
node: {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
performance: false,
};
i am just clueless where to edit above code to solve my problem, i also observed that css in build folder has '#' at the beginning
Project build folder image
I think you'll need to add a css loader to your plugins. You'll have to
npm install css-loader style-loader --save-dev
Add a plugin to to your webpack.config.js
module:{
rules:[
// other plugins
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
}
Now webpack should bundle your css properly. Note you have to make sure you have imported you css file into your application !
import '../app.css';
Run webpack again and you should see the css inserted in s style tag in the header of your html page
I'm trying to get a dist folder populated with the standard files + the .gz version of them. I did ng eject to get the webpack.config.js file so I could add the compression plugin https://github.com/webpack-contrib/compression-webpack-plugin. I added the new CompressPlugin({}) as the last plugin and marked the ejected: false in the .angular-cli.json file.
When I then run ng build I don't get any .gzip/.gz files generated which I would expect have.
Is there something I am missing or doing wrong? The full webpack file (mostly generated by ng new is:
const fs = require('fs');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer');
const postcssUrl = require('postcss-url');
const cssnano = require('cssnano');
const CompressionPlugin = require("compression-webpack-plugin");
const { NoEmitOnErrorsPlugin, SourceMapDevToolPlugin, NamedModulesPlugin } = require('webpack');
const { NamedLazyChunksWebpackPlugin, BaseHrefWebpackPlugin } = require('#angular/cli/plugins/webpack');
const { CommonsChunkPlugin } = require('webpack').optimize;
const { AotPlugin } = require('#ngtools/webpack');
const nodeModules = path.join(process.cwd(), 'node_modules');
const realNodeModules = fs.realpathSync(nodeModules);
const genDirNodeModules = path.join(process.cwd(), 'src', '$$_gendir', 'node_modules');
const entryPoints = ["inline","polyfills","sw-register","styles","vendor","main"];
const minimizeCss = false;
const baseHref = "";
const deployUrl = "";
const postcssPlugins = function () {
// safe settings based on: https://github.com/ben-eb/cssnano/issues/358#issuecomment-283696193
const importantCommentRe = /#preserve|#license|[##]\s*source(?:Mapping)?URL|^!/i;
const minimizeOptions = {
autoprefixer: false,
safe: true,
mergeLonghand: false,
discardComments: { remove: (comment) => !importantCommentRe.test(comment) }
};
return [
postcssUrl({
url: (URL) => {
// Only convert root relative URLs, which CSS-Loader won't process into require().
if (!URL.startsWith('/') || URL.startsWith('//')) {
return URL;
}
if (deployUrl.match(/:\/\//)) {
// If deployUrl contains a scheme, ignore baseHref use deployUrl as is.
return `${deployUrl.replace(/\/$/, '')}${URL}`;
}
else if (baseHref.match(/:\/\//)) {
// If baseHref contains a scheme, include it as is.
return baseHref.replace(/\/$/, '') +
`/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
}
else {
// Join together base-href, deploy-url and the original URL.
// Also dedupe multiple slashes into single ones.
return `/${baseHref}/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
}
}
}),
autoprefixer(),
].concat(minimizeCss ? [cssnano(minimizeOptions)] : []);
};
module.exports = {
"resolve": {
"extensions": [
".ts",
".js"
],
"modules": [
"./node_modules",
"./node_modules"
],
"symlinks": true
},
"resolveLoader": {
"modules": [
"./node_modules",
"./node_modules"
]
},
"entry": {
"main": [
"./src\\main.ts"
],
"polyfills": [
"./src\\polyfills.ts"
],
"styles": [
"./src\\styles.css"
]
},
"output": {
"path": path.join(process.cwd(), "dist"),
"filename": "[name].bundle.js",
"chunkFilename": "[id].chunk.js"
},
"module": {
"rules": [
{
"enforce": "pre",
"test": /\.js$/,
"loader": "source-map-loader",
"exclude": [
/(\\|\/)node_modules(\\|\/)/
]
},
{
"test": /\.html$/,
"loader": "raw-loader"
},
{
"test": /\.(eot|svg|cur)$/,
"loader": "file-loader?name=[name].[hash:20].[ext]"
},
{
"test": /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
"loader": "url-loader?name=[name].[hash:20].[ext]&limit=10000"
},
{
"exclude": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.css$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
}
]
},
{
"exclude": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.scss$|\.sass$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "sass-loader",
"options": {
"sourceMap": false,
"precision": 8,
"includePaths": []
}
}
]
},
{
"exclude": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.less$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "less-loader",
"options": {
"sourceMap": false
}
}
]
},
{
"exclude": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.styl$/,
"use": [
"exports-loader?module.exports.toString()",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "stylus-loader",
"options": {
"sourceMap": false,
"paths": []
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.css$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.scss$|\.sass$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "sass-loader",
"options": {
"sourceMap": false,
"precision": 8,
"includePaths": []
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.less$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "less-loader",
"options": {
"sourceMap": false
}
}
]
},
{
"include": [
path.join(process.cwd(), "src\\styles.css")
],
"test": /\.styl$/,
"use": [
"style-loader",
{
"loader": "css-loader",
"options": {
"sourceMap": false,
"importLoaders": 1
}
},
{
"loader": "postcss-loader",
"options": {
"ident": "postcss",
"plugins": postcssPlugins
}
},
{
"loader": "stylus-loader",
"options": {
"sourceMap": false,
"paths": []
}
}
]
},
{
"test": /\.ts$/,
"loader": "#ngtools/webpack"
}
]
},
"plugins": [
new NoEmitOnErrorsPlugin(),
new CopyWebpackPlugin([
{
"context": "src",
"to": "",
"from": {
"glob": "assets/**/*",
"dot": true
}
},
{
"context": "src",
"to": "",
"from": {
"glob": "favicon.ico",
"dot": true
}
}
], {
"ignore": [
".gitkeep"
],
"debug": "warning"
}),
new ProgressPlugin(),
new CircularDependencyPlugin({
"exclude": /(\\|\/)node_modules(\\|\/)/,
"failOnError": false
}),
new NamedLazyChunksWebpackPlugin(),
new HtmlWebpackPlugin({
"template": "./src\\index.html",
"filename": "./index.html",
"hash": false,
"inject": true,
"compile": true,
"favicon": false,
"minify": false,
"cache": true,
"showErrors": true,
"chunks": "all",
"excludeChunks": [],
"title": "Webpack App",
"xhtml": true,
"chunksSortMode": function sort(left, right) {
let leftIndex = entryPoints.indexOf(left.names[0]);
let rightindex = entryPoints.indexOf(right.names[0]);
if (leftIndex > rightindex) {
return 1;
}
else if (leftIndex < rightindex) {
return -1;
}
else {
return 0;
}
}
}),
new BaseHrefWebpackPlugin({}),
new CommonsChunkPlugin({
"name": [
"inline"
],
"minChunks": null
}),
new CommonsChunkPlugin({
"name": [
"vendor"
],
"minChunks": (module) => {
return module.resource
&& (module.resource.startsWith(nodeModules)
|| module.resource.startsWith(genDirNodeModules)
|| module.resource.startsWith(realNodeModules));
},
"chunks": [
"main"
]
}),
new SourceMapDevToolPlugin({
"filename": "[file].map[query]",
"moduleFilenameTemplate": "[resource-path]",
"fallbackModuleFilenameTemplate": "[resource-path]?[hash]",
"sourceRoot": "webpack:///"
}),
new CommonsChunkPlugin({
"name": [
"main"
],
"minChunks": 2,
"async": "common"
}),
new NamedModulesPlugin({}),
new AotPlugin({
"mainPath": "main.ts",
"replaceExport": false,
"hostReplacementPaths": {
"environments\\environment.ts": "environments\\environment.ts"
},
"exclude": [],
"tsConfigPath": "src\\tsconfig.app.json",
"skipCodeGeneration": true
}),
new CompressionPlugin({})
],
"node": {
"fs": "empty",
"global": true,
"crypto": "empty",
"tls": "empty",
"net": "empty",
"process": true,
"module": false,
"clearImmediate": false,
"setImmediate": false
},
"devServer": {
"historyApiFallback": true
}
};
I'm using #angular/cli 1.4.4.
Note the main reason why I'm doing that is to improve some SEO recommendations because apparently my vendor.css is 600Kb big and being pointed out in the PageSpeed Ingishts: Your page has 1 blocking CSS resources. This causes a delay in rendering your page. It contains 3rd party css only - actually only bootstrap + font-awesome. Unless there is something else to prevent this I thought of compression. I also thought that the web server would auto compress and serve .gz files but I don't know whether that test would apply.
Any help is much appreciated! Thanks
Only ejected application's build is processed by exposed on the root webpack.config.js file. Application which is not ejected (or set to ejected: false) will completely ignore this webpack.config.js file.
So in order to use gzipped files you will need to work with ejected app and use new npm scripts automatically added to package.json.
Instead of 'ng build', now you should run:
npm run build
my related answers that may help:
Angular4 build - gzip missing
How to undo Angular 2 Cli ng-eject