Webpack gzip bundle - Uncaught SyntaxError: Unexpected token < - reactjs

I am working on a react project using webpack for bundling. I wanted to reduce my bundle size so decided to use a compression plugin to serve a gzip file to get a nice small bundle size. The project builds fine and I get a nice small bundle size but here's my issues..when I go to serve my current project here is the error i get:
Looking into I realized that for whatever reason instead of serving the contents of main.js or vendor.js it's returning my index.html file
I am fairly certain my apache server is configured to handle gzip encoding this as I can see it in the response header:
Here is the webpack config I am using:
const appConstants = function() {
switch (process.env.NODE_ENV) {
case 'local':
const localConfig = require('./config/local');
return localConfig.config();
case 'development':
const devConfig = require('./config/development');
return devConfig.config();
case 'production':
default:
const prodConfig = require('./config/production');
return prodConfig.config();
}
};
const HtmlWebPackPlugin = require("html-webpack-plugin");
const webpack = require('webpack');
const CompressionPlugin = require('compression-webpack-plugin');
const htmlWebpackPlugin = new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html",
hash: true
});
const compressionPlugin = new CompressionPlugin({
filename: "[path].gz[query]",
test: /\.(js|css)$/,
algorithm: 'gzip',
deleteOriginalAssets: true
});
let webpackConfig = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
exclude: [ /assets/, /node_modules/ ],
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
localIdentName: "[name]_[local]_[hash:base64]",
sourceMap: true,
minimize: true
}
}
]
},
{
test: /\.(pdf|jpg|png|gif|svg|ico)$/,
exclude: [/node_modules/],
use: [
{
loader: 'file-loader'
},
]
},
{
test: /\.(woff|woff2|eot|ttf|svg)$/,
exclude: [/node_modules/],
use: {
loader: 'url-loader?limit100000'
}
}
]
},
entry: [ "#babel/polyfill", "./src/index.js"],
output: {
publicPath: appConstants().DS_BASENAME ? JSON.parse(appConstants().DS_BASENAME) : '/',
chunkFilename: '[name].[chunkhash].js'
},
optimization: {
splitChunks: {
chunks: 'all',
},
},
plugins: [
htmlWebpackPlugin,
compressionPlugin,
new webpack.DefinePlugin({
'process.env': appConstants()
}),
new webpack.EnvironmentPlugin(['NODE_ENV']),
],
devServer: {
historyApiFallback: true
}
};
// configure source map per-env
if (process.env.NODE_ENV === 'local') {
webpackConfig.devtool = 'source-map';
} else {
webpackConfig.devtool = 'hidden-source-map';
}
module.exports = webpackConfig;
I cannot figure out why the gzip is not being read/recognized by the browser. I've tried several post with similar issues but no solutions.

You need to add middleware function to handle .js and .css file with suffix .gz
Like that
const app = express()
app.get('*.js', function(req, res, next) {
req.url = req.url + '.gz'
res.set('Content-Encoding', 'gzip')
res.set('Content-Type', 'text/javascript')
next()
})
app.get('*.css', function(req, res, next) {
req.url = req.url + '.gz'
res.set('Content-Encoding', 'gzip')
res.set('Content-Type', 'text/css')
next()
})
app.use('/dist', serve('./dist', true))
app.use(express.static('./dist'));
You have to add middleware function before express.static
Good luck!

Related

Webpack production request https

I have a problem. I am using axios to make a request to a http target, but when building the code, the bundle request to a https as show in the picture.
Maybe I need to do some configuration on my webpack config.
correct target: http://ip-api.com/json
wrong target: https://ip-api.com/json
webpack.prod.config.js
const common = require('./webpack.common.config')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = merge(common, {
mode: 'production',
module: {
rules: [
{
test: /\.ts(x?)$/,
loader: 'ts-loader',
exclude: /node_module/
},
{
test: /\.scss$/,
use: [{
loader: MiniCssExtractPlugin.loader
}, {
loader: 'css-loader',
options: {
modules: true
}
}, {
loader: 'sass-loader'
}
]
}
]
},
devtool: 'cheap-module-source-map',
externals: {
axios: 'axios',
react: 'React',
'react-dom': 'ReactDOM'
},
plugins: [
new HtmlWebpackPlugin({
template: './template.prod.html'
}),
new MiniCssExtractPlugin({
filename: 'main-bundle-[hash].css'
})
// new FaviconsWebpackPlugin({
// logo: './public/static/img/favicon.png',
// inject: true
// })
]
})
I have found the solutions. I removed <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" /> from my template.prod.html and the problem was solved.

How to resolve aliases in Storybook?

I have a React/Typescript project with Storybook. Storybook works great, but as soon as I start importing files with aliases, it crashes.
Example:
import Foo from "#components/foo" => crash
import Foo from "../../components/foo" => ok
The app works fine with the aliases. The issue is only related to Storybook.
Here is my storybook config:
module.exports = {
stories: ["../**/stories.tsx"],
webpackFinal: (config) => {
return {
...config,
module: {
...config.module,
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: { loader: "babel-loader" },
},
{ test: /\.css$/, use: ["style-loader", "css-loader"] },
{ test: /\.(png|jpg|gif)$/, use: ["file-loader"] },
{
test: /\.svg$/,
use: [
{
loader: "babel-loader",
},
{
loader: "react-svg-loader",
options: {
jsx: true,
},
},
],
},
],
},
};
},
typescript: {
check: false,
checkOptions: {},
reactDocgen: "react-docgen-typescript",
reactDocgenTypescriptOptions: {
shouldExtractLiteralValuesFromEnum: true,
propFilter: (prop) =>
prop.parent ? !/node_modules/.test(prop.parent.fileName) : true,
},
},
};
My webpack config:
/* eslint-env node */
const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
const Dotenv = require("dotenv-webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const isProductionMode = (mode) => mode === "production";
module.exports = () => {
const env = require("dotenv").config({ path: __dirname + "/.env" });
const nodeEnv = env.parsed.NODE_ENV;
return {
mode: "development",
entry: "./src/index.tsx",
output: {
path: path.join(__dirname, "./dist"),
filename: "[name].[contenthash].bundle.js",
publicPath: "/",
},
resolve: {
extensions: [".ts", ".tsx", ".js", "jsx", ".json"],
alias: {
"#api": path.resolve(__dirname, "src/api/"),
"#assets": path.resolve(__dirname, "src/assets/"),
"#components": path.resolve(__dirname, "src/components/"),
"#containers": path.resolve(__dirname, "src/containers/"),
"#data": path.resolve(__dirname, "src/data/"),
"#i18n": path.resolve(__dirname, "src/i18n/"),
"#models": path.resolve(__dirname, "src/models/"),
"#pages": path.resolve(__dirname, "src/pages/"),
"#src": path.resolve(__dirname, "src/"),
"#stores": path.resolve(__dirname, "src/stores/"),
"#utils": path.resolve(__dirname, "src/utils/"),
},
},
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: { loader: "babel-loader" },
},
{ test: /\.css$/, use: ["style-loader", "css-loader"] },
{ test: /\.(png|jpg|jpeg|gif)$/, use: ["file-loader"] },
{
test: /\.svg$/,
use: [
{
loader: "babel-loader",
},
{
loader: "react-svg-loader",
options: {
jsx: true,
},
},
],
},
],
},
devServer: {
historyApiFallback: true,
port: 3000,
inline: true,
hot: true,
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
new Dotenv(),
],
optimization: {
minimize: isProductionMode(nodeEnv),
minimizer: isProductionMode(nodeEnv) ? [new TerserPlugin()] : [],
splitChunks: { chunks: "all" },
},
};
};
How to fix this? I am on webpack 5.24.2 and storybook 6.1.20, so these are the latest versions.
Just add this in your .storybook/main.js
const path = require('path');
module.exports = {
"stories": [
"../components/**/*.stories.mdx",
"../components/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
'#storybook/preset-scss',
],
webpackFinal: async (config, { configType }) => {
config.resolve.alias = {
...config.resolve.alias,
'#/interfaces': path.resolve(__dirname, "../interfaces"),
};
return config;
}
}
here interface is folder at my project root
It works For Me
This worked for me when I had the same problem:
Install a package in dev deps yarn add -D tsconfig-paths-webpack-plugin.
Then adjust your ./storybook/main.js config:
... // other imports
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
...
webpackFinal: (config) => {
config.resolve.plugins = config.resolve.plugins || [];
config.resolve.plugins.push(
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, "../tsconfig.json"),
})
);
return { ... }
}
...
From the docs:
// .storybook/main.js
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
webpackFinal: async (config) => {
config.resolve.plugins = [
...(config.resolve.plugins || []),
new TsconfigPathsPlugin({
extensions: config.resolve.extensions,
}),
];
return config;
},
};
Link
My React/TypeScript Storybook project uses Vite rather than Webpack.
The readme for storybook-builder-vite clarifies "The builder will not read your vite.config.js file by default," so anything that you specified in there may be having no influence whatsoever on the Storybook build; instead, you have to customise the Storybook-specific Vite config via the viteFinal option in .storybook/main.js.
Here's how I went about introducing vite-tsconfig-paths into the Storybook Vite config to resolve tsconfig path aliases:
// .storybook/main.js
const path = require("path");
const tsconfigPaths = require("vite-tsconfig-paths").default;
module.exports = {
"stories": [
"../frontend/**/*.stories.mdx",
"../frontend/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials",
"#storybook/addon-interactions"
],
"framework": "#storybook/react",
"core": {
"builder": "storybook-builder-vite"
},
/**
* A option exposed by storybook-builder-vite for customising the Vite config.
* #see https://github.com/eirslett/storybook-builder-vite#customize-vite-config
* #param {import("vite").UserConfig} config
* #see https://vitejs.dev/config/
*/
viteFinal: async (config) => {
config.plugins.push(
/** #see https://github.com/aleclarson/vite-tsconfig-paths */
tsconfigPaths({
// My tsconfig.json isn't simply in viteConfig.root,
// so I've passed an explicit path to it:
projects: [path.resolve(path.dirname(__dirname), "frontend", "tsconfig.json")],
})
);
return config;
},
}
In case you use #storybook/vite-builder. This neat config works for me
const tsconfigPaths = require("vite-tsconfig-paths");
...
module.exports = {
...
async viteFinal(config) {
return {
...config,
plugins: [...config.plugins, tsconfigPaths.default()],
};
},
};
If you're using webpack 5 you'll need to specify that webpack5 should be used by also adding the following in addition to the previous answers:
core: {
builder: "webpack5",
},
Final storybook/main.js would then resemble:
// .storybook/main.js
const path = require('path');
const appWebpack = require(path.join(process.cwd(), 'webpack.config.js'));
module.exports = {
stories: ['../src/**/*.stories.#(tsx|mdx)'],
addons: [
"#storybook/addon-links",
"#storybook/addon-essentials",
'#storybook/preset-scss'
],
core: {
builder: "webpack5",
},
webpackFinal: async (config) => {
config.resolve.modules = [
...(config.resolve.modules || []),
...[path.resolve(process.cwd(), "src")],
];
config.resolve.alias = {
...(config.resolve.alias || {}),
...appWebpack().resolve.alias,
};
return config;
},
};
This will allow both absolute paths as well as aliases (as long as those aliases are properly set up in your main webpack.config.js and jsconfig.json/tsconfig.json of course)
Edited
Having trouble after the fact specifically with aliases, I took another trip down the webpack rocky-road.
I've updated the original 'final' for the .storybook/main.js above, explicitly merging in the alias as well as the modules nodes.
Edit 2
Be aware, eslint is going to squawk over using an alias within global decorators you create (and add to .storybook/preview.js). You can safely ignore this - they still work. If/when I figure out how to correct this as well, I'll come back and add a 3rd edit.
We're using Vite and typescript project references, for us adding the following to the storybook main.cjs worked;
viteFinal: async (config) => {
config.resolve.alias = {
...config.resolve.alias,
'#some-alias': path.resolve(__dirname, '../../some/ts/project/reference'),
};
return config;
}
As an alternative to Jamie Birch's excellent answer, if you're using vite and don't want to install vite-tsconfig-paths, you can just edit .storybook/main.js and add viteFinal to the config, like this:
const path = require('path');
module.exports = {
// ... whatever you already have here
viteFinal: async (config) => {
if (config.resolve.alias) {
config.resolve.alias.push({ find: '#', replacement: path.resolve(__dirname, '../src') + '/' });
} else {
config.resolve.alias = [{ find: '#', replacement: path.resolve(__dirname, '../src') + '/' }];
}
return config;
}
}

React Loadable Problem In My React Website

Can someone help me with the Issue in my React Website?
We have used react-loadable for chunks whenever we deploy it on production environment the website get stuck on the loading part. Below is the URL
URL WITH LOADABLE: http://fcastage.surge.sh/
Any help will be appreciated.
We have tried making the website using react loadabale and without react loadable. But to make the website fast and load in chunks we have to use loadable . The react loadable is working fine with Development Environment but its not working when I am switching to Production.
Below is the Config File for Production
const HtmlWebpackPlugin = require("html-webpack-plugin");
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const path = require("path")
const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { ReactLoadablePlugin } = require('react-loadable/webpack')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
mode: "production",
entry: "./app/index.js",
output: {
path: path.resolve(__dirname, "./build"),
filename: '[name].bundle.js',
chunkFilename: '[name].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
//because remove style-loader,my css can't work
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
localIdentName: "[local]"
} // translates CSS into CommonJS
},
{
loader: "less-loader" // compiles Sass to CSS
}
]
})
},
{
test: /\.(jpe?g|png|gif|svg|ico)$/i,
use: [
{
loader: "url-loader",
options: {
outputPath: "assets/",
limit: 10 * 1024
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf)$/i,
use: [
{
loader: "url-loader",
options: {
outputPath: "assets/"
}
}
]
}
]
},
optimization : {
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
}
}
}
// minimizer: [
// new UglifyJsPlugin({
// uglifyOptions: {
// compress: {
// unused: true,
// dead_code: true,
// warnings: false
// }
// },
// sourceMap: true
// }),
// ]
},
plugins: [
new HtmlWebpackPlugin({
template: "./app/index.html",
hash: true,
filename: "index.html"
}),
//for surge.sh
new HtmlWebpackPlugin({
template: "./app/index.html",
hash: true,
filename: "200.html"
}),
new CleanWebpackPlugin(),
new ExtractTextPlugin("main.css"),
new webpack.DefinePlugin( {'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.DEBUG': JSON.stringify(process.env.DEBUG) } ),
new ReactLoadablePlugin({
filename: path.resolve(__dirname, "build/react-loadable.json")
})
],
};

i18next + React + Webpack - getFixedT is not a function

I'm having some trouble with React, i18next and Webpack. I've tried many solutions, but none of them worked. When I try to build my application, it builds successfully. But, when I try to open it, the console shows an error. My webpack.config and the error stacktrace are below.
webpack.prod.config.js
const webpack = require('webpack');
const path = require('path');
const htmlWebpackPlugin = require("html-webpack-plugin")
const miniCSSExtractPlugin = require("mini-css-extract-plugin")
const terserPlugin = require("terser-webpack-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")
const cleanWebpackPlugin = require("clean-webpack-plugin")
const i18nPlugin = require("i18n-webpack-plugin")
const options = require("../src/controllers/i18n").options
const locales = require("../src/controllers/i18n/locales")
options.backend.loadPath = "." + options.backend.loadPath
const config = {
mode: "production",
output: {
path: path.resolve(__dirname, '../dist'),
publicPath: "./",
filename: 'bundle.js'
},
resolve: {
extensions: [" ", ".js", ".jsx"],
alias: {
"#components": path.resolve(__dirname, "../src/components"),
"#views": path.resolve(__dirname, "../src/views")
}
},
optimization: {
minimizer: [
new terserPlugin({
cache: true,
parallel: true,
include: /\.(js|jsx)$/
}),
new OptimizeCSSAssetsPlugin({})
]
},
module: {
rules: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [{
loader: "babel-loader"
}, {
loader: "i18next-loader"
}]
},
{
test: /\.css$/,
use: [
miniCSSExtractPlugin.loader,
{
loader: "css-loader",
}
]
}, {
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'file-loader?name=images/[hash].[ext]',
options: {
name: "assets/images/[hash].[ext]"
}
}]
}, {
test: /\.(ttf|woff(2)|eof|svg)$/,
use: [{
loader: "file-loader",
options: {
name: "assets/fonts/[hash].[ext]",
}
}]
}
],
},
plugins: [
new htmlWebpackPlugin({
template: path.join(__dirname, "..", "public", "index.html")
}),
new miniCSSExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
new cleanWebpackPlugin("../dist/*", {
root: __dirname + "../",
allowExternal: true
}),
new i18nPlugin(locales,{
functionName: "t",
nested: true
},true)
]
};
module.exports = config;
The npm run build runs normally, no errors about i18next. Then, when I open the application, I got this error:
bundle.js:33 TypeError: r.getFixedT is not a function
at L (bundle.js:12)
at bundle.js:12
at Xo (bundle.js:33)
at Ia (bundle.js:33)
at qi (bundle.js:33)
at $i (bundle.js:33)
at jl (bundle.js:33)
at Cl (bundle.js:33)
at Pl (bundle.js:33)
at Ji (bundle.js:33)
Hope somebody can helps me.
I've found what was the problem. The i18next documentation says that I should run the init inside the webpack.config.js.
The Problem
My initial problem was loading the locales. The i18n couldn't find the files after the build, because the webpack doesn't recognize the i18n-xhr-backend requiring the .json files. After the build, there was no translation files. Then, I've tried to let webpack deal with the i18n, and I got another problem, on next paragraph.
The React needs the i18n instance to be add to the i18nextProvider. But, the way that I was doing it, there was no i18n instance to refence inside React. Then, it coudn't find the translation function or anything else. I've also found the i18nWebpackPlugin, but it also didn't solved my problem, because it don't give access to the i18n instance inside react. At the end, I had two unsolved problems.
The Solution
My solution was quite simple. I've created a new i18n config to the development env and let the webpack deal with the .json, copying it to a new folder after build. I'll let my webpack and i18n config files below. The steps were:
Bring i18n.init() back to i18n/index.js
Create different options for each environment
Configure webpack to copy translation files
Import the i18n instance on App.js again
Now, everything works like a charm.
OBS: To webpack recognize the .json files, you need to import it somewhere. I did inside the resources.js file.
webpack.prod.config.js
const webpack = require("webpack");
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
const miniCSSExtractPlugin = require("mini-css-extract-plugin");
const terserPlugin = require("terser-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const cleanWebpackPlugin = require("clean-webpack-plugin");
const config = {
mode: "production",
output: {
path: path.resolve(__dirname, "../dist"),
publicPath: "./",
filename: "bundle.js"
},
resolve: {
extensions: [" ", ".js", ".jsx"],
alias: {
"#components": path.resolve(__dirname, "../src/components"),
"#views": path.resolve(__dirname, "../src/views"),
"#static": path.resolve(__dirname, "../src/static")
}
},
optimization: {
minimizer: [
new terserPlugin({
cache: true,
parallel: true,
include: /\.(js|jsx)$/
}),
new OptimizeCSSAssetsPlugin({})
]
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader"
}
]
},
{
test: /\.css$/,
use: [
miniCSSExtractPlugin.loader,
{
loader: "css-loader"
}
]
},
{
test: /\.(png|jpg|gif|ico)$/,
use: [
{
loader: "file-loader?name=images/[hash].[ext]",
options: {
name: "assets/images/[hash].[ext]"
}
}
]
},
{
test: /\.(ttf|woff2?|eo(f|t)|svg)$/,
use: [
{
loader: "file-loader",
options: {
name: "assets/fonts/[hash].[ext]"
}
}
]
},
{
test: /\.(json)$/,
type: "javascript/auto",
use: [
{
loader: "file-loader",
options: {
name: "[folder]/[name].[ext]",
outputPath: "assets/locales/"
}
}
]
}
]
},
plugins: [
new htmlWebpackPlugin({
template: path.join(__dirname, "..", "public", "index.html")
}),
new miniCSSExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
new cleanWebpackPlugin("../dist/*", {
root: __dirname + "../",
allowExternal: true
})
]
};
module.exports = config;
i18n/index.js
const i18n = require("i18next");
const initReactI18next = require("react-i18next").initReactI18next;
const langDetector = require("i18next-browser-languagedetector");
const backend = require("i18next-xhr-backend");
const moment = require("moment");
const resources = require("../../static/locales");
/*
Other codes...
*/
i18n.use(langDetector).use(initReactI18next);
var options;
switch (process.env.NODE_ENV) {
case "test":
options = {
whitelist: ["en", "pt"],
fallbackLng: "en",
resources,
ns: "translation",
defaultNS: "translation",
interpolation: {
format: function(value, format, lng) {
if (value instanceof Date) return moment(value).format(format);
return value.toString();
}
}
};
break;
case "production":
i18n.use(backend);
options = {
whitelist: ["en-US", "pt-BR"],
fallbackLng: {
pt: ["pt-BR"],
en: ["en-US"],
default: ["en"]
},
ns: ["button", "common", "lng", "info"],
defaultNS: "common",
backend: {
loadPath: "./assets/locales/{{lng}}/{{ns}}.json"
},
detection: {
order: ["querystring", "cookie", "navigator", "localStorage"]
},
lookupQuerystring: "lng",
caches: ["localStorage", "cookie"],
react: {
wait: true
},
interpolation: {
format: function(value, format, lng) {
if (format === "uppercase") return value.toUpperCase();
if (value instanceof Date) return moment(value).format(format);
return value;
}
}
};
break;
case "development":
i18n.use(backend);
options = {
whitelist: ["en-US", "pt-BR"],
fallbackLng: {
pt: ["pt-BR"],
en: ["en-US"],
default: ["en"]
},
ns: ["button", "common", "lng", "info"],
defaultNS: "common",
backend: {
loadPath: "./src/static/locales/{{lng}}/{{ns}}.json"
},
detection: {
order: ["querystring", "cookie", "navigator", "localStorage"]
},
lookupQuerystring: "lng",
caches: ["localStorage", "cookie"],
react: {
wait: true
},
interpolation: {
format: function(value, format, lng) {
if (format === "uppercase") return value.toUpperCase();
if (value instanceof Date) return moment(value).format(format);
return value;
}
}
};
break;
}
i18n.init(options);
module.exports = i18n;

Webpack running through grunt webpack doesn't error or complete, or do anything

Trying to convert an old system off bower into npm using webpack, and grunt webpack. Just trying to use webpack to load in NPM files, not run anything else, and the rest of the grunt file finishes loading and uglifying and stuff, and runs its own node server. It gets to this point and freezes and never comes back.
Loading "grunt-webpack" plugin
Registering "/Users/***/***/***/node_modules/grunt-webpack/tasks" tasks.
Loading "webpack-dev-server.js" tasks...OK
+ webpack-dev-server
Loading "webpack.js" tasks...OK
+ webpack
Running "webpack" task
Here's my grunt code (super basic obviously)
webpack: {
options: require("./config/webpack.dev.js"),
},
Here's that dev file
const webpack = require('webpack');
const helpers = require('./helpers');
const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { BaseHrefWebpackPlugin } = require('base-href-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ConcatPlugin = require('webpack-concat-plugin');
const ngInventory = require('./ng1-vendor-index.js');
const common = require('./webpack.common.js');
const ENV = process.env.NODE_ENV = process.env.ENV = 'dev';
module.exports = merge(common(ENV), {
devtool: 'source-map',
module: {
rules: [
{
test: /\.(ts|js)$/,
loaders: ['angular-router-loader'],
},
{
test: /\.((s*)css)$/,
use: [{
loader: 'style-loader',
},{
loader: 'css-loader',
},{
loader: 'sass-loader',
}]
},
{
test: /src\/.+\.(ts|js)$/,
exclude: /(node_modules|\.spec\.ts$)/,
loader: 'istanbul-instrumenter-loader',
enforce: 'post',
options: {
esModules: true
}
}
]
},
debug: true,
devTool: 'eval',
plugins: [
new ConcatPlugin({
uglify: false,
sourceMap: true,
name: 'vendor',
outputPath: './',
fileName: '[name].[hash].js',
filesToConcat: ngInventory.vendor1
}),
new BaseHrefWebpackPlugin({ baseHref: '/'}),
new HtmlWebpackPlugin({
favicon: helpers.root('client/assets/image/favicon.png'),
template: "./client/index.html",
filename: "./client/index.html",
}),
new webpack.NoEmitOnErrorsPlugin(),
],
});
And here is the common file:
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals')
const helpers = require('./helpers');
module.exports = env => ({
entry: {
server: './server/app.js',
},
resolve: {
extensions: ['.ts', '.js']
},
output: {
path: helpers.root(`dist/${env}`),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()],
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
include: [
helpers.root('client'),
],
loader: 'html-loader'
},
{
test: /\.((s*)css)%/,
include: [
helpers.root('client/app'),
helpers.root('client/components'),
],
exclude: 'node_modules/',
loaders: ['to-string-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(woff|woff2|eot|tts)$/,
use: [{
loader: 'file-loader'
}]
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(env)
}
}),
new webpack.ContextReplacementPlugin(/\#angular(\\|\/)core(\\|\/)esm5/, path.join(__dirname, './client')),
]
});
A sample from the vendor index file:
const helper = require('./helpers');
exports.vendor1 = [
helper.root('node_modules/lodash/lodash.js'),
helper.root('node_modules/lodash-deep/lodash-deep.js'),
...
...
]
I'm just really not sure what to do, couldn't bring up any google results or stack results because theres no errors happening either. I've tried all verbose levels of logging all to no avail. What in the world am I missing?
As the documentation shows, you haven't configured any targets, like dev or prod. You've only specified options. You want
webpack: {
options: {},
dev: require("./config/webpack.dev.js"),
},
As an aside, there's no benefit to using Webpack with Grunt.

Resources