On compiling an app and trying to implement the i18n library with webpack, I face this error:
ERROR in ./node_modules/bundle-loader?lazy&name=lang-pt!./src/locales/pt/translation.json
Module parse failed: Unexpected token m in JSON at position 0
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token m in JSON at position 0
at JSON.parse (<anonymous>)
at JsonParser.parse (C:\Users\vasco.bento\ContactosWebPack\node_modules\webpack\lib\JsonParser.js:15:21)
at doBuild.err (C:\Users\vasco.bento\ContactosWebPack\node_modules\webpack\lib\NormalModule.js:367:32)
at runLoaders (C:\Users\vasco.bento\ContactosWebPack\node_modules\webpack\lib\NormalModule.js:264:12)
at C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\LoaderRunner.js:370:3
at iterateNormalLoaders (C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\LoaderRunner.js:211:10)
at C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\LoaderRunner.js:183:6
at runSyncOrAsync (C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\LoaderRunner.js:130:11)
at C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\LoaderRunner.js:175:3
at loadLoader (C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\loadLoader.js:36:3)
at iteratePitchingLoaders (C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\LoaderRunner.js:169:2)
at runLoaders (C:\Users\vasco.bento\ContactosWebPack\node_modules\loader-runner\lib\LoaderRunner.js:362:2)
at NormalModule.doBuild (C:\Users\vasco.bento\ContactosWebPack\node_modules\webpack\lib\NormalModule.js:219:3)
at NormalModule.build (C:\Users\vasco.bento\ContactosWebPack\node_modules\webpack\lib\NormalModule.js:337:15)
at Compilation.buildModule (C:\Users\vasco.bento\ContactosWebPack\node_modules\webpack\lib\Compilation.js:346:10)
at factory.create (C:\Users\vasco.bento\ContactosWebPack\node_modules\webpack\lib\Compilation.js:572:15)
# ./node_modules/aurelia-i18n/dist/native-modules/aurelia-i18n.js
# ./src/main.js
# ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
# multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry aurelia-bootstrapper
ERROR in chunk app [entry]
[name].[hash].bundle.js
Cannot read property 'replace' of undefined
This repeats for the other language I have in the locales folder, which is correctly placed in the src folder, even if the JSON files are completely empty, the same error occurs.
Here's the webconfig.js file:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const project = require('./aurelia_project/aurelia.json');
const {
AureliaPlugin,
ModuleDependenciesPlugin
} = require('aurelia-webpack-plugin');
const {
ProvidePlugin
} = require('webpack');
const {
BundleAnalyzerPlugin
} = require('webpack-bundle-analyzer');
// config helpers:
const ensureArray = (config) => config && (Array.isArray(config) ? config : [config]) || [];
const when = (condition, config, negativeConfig) =>
condition ? ensureArray(config) : ensureArray(negativeConfig);
// primary config:
const title = 'Aurelia Navigation Skeleton';
const outDir = path.resolve(__dirname, project.platform.output);
const srcDir = path.resolve(__dirname, 'src');
const nodeModulesDir = path.resolve(__dirname, 'node_modules');
const baseUrl = '/';
const cssRules = [{
loader: 'css-loader'
}];
module.exports = ({
production,
server,
extractCss,
coverage,
analyze
} = {}) => ({
resolve: {
extensions: ['.js'],
modules: [srcDir, 'node_modules']
},
entry: {
app: ['aurelia-bootstrapper'],
vendor: ['bluebird']
},
mode: production ? 'production' : 'development',
output: {
path: outDir,
publicPath: baseUrl,
filename: production ? '[name].[chunkhash].bundle.js' : '[name].[hash].bundle.js',
sourceMapFilename: production ? '[name].[chunkhash].bundle.map' : '[name].[hash].bundle.map',
chunkFilename: production ? '[name].[chunkhash].chunk.js' : '[name].[hash].chunk.js'
},
performance: {
hints: false
},
devServer: {
contentBase: outDir,
// serve index.html for all 404 (required for push-state)
historyApiFallback: true
},
devtool: production ? 'nosources-source-map' : 'cheap-module-eval-source-map',
module: {
rules: [
// CSS required in JS/TS files should use the style-loader that auto-injects it into the website
// only when the issuer is a .js/.ts file, so the loaders are not applied inside html templates
{
test: /\.css$/i,
issuer: [{
not: [{
test: /\.html$/i
}]
}],
use: extractCss ? ExtractTextPlugin.extract({
fallback: 'style-loader',
use: cssRules
}) : ['style-loader', ...cssRules]
},
{
test: /\.css$/i,
issuer: [{
test: /\.html$/i
}],
// CSS required in templates cannot be extracted safely
// because Aurelia would try to require it again in runtime
use: cssRules
},
{
test: /\.html$/i,
loader: 'html-loader'
},
{
test: /\.js$/i,
loader: 'babel-loader',
exclude: nodeModulesDir,
options: coverage ? {
sourceMap: 'inline',
plugins: ['istanbul']
} : {}
},
{
test: /\.json$/i,
loader: 'json-loader'
},
// use Bluebird as the global Promise implementation:
{
test: /[\/\\]node_modules[\/\\]bluebird[\/\\].+\.js$/,
loader: 'expose-loader?Promise'
},
// embed small images and fonts as Data Urls and larger ones as files:
{
test: /\.(png|gif|jpg|cur)$/i,
loader: 'url-loader',
options: {
limit: 8192
}
},
{
test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i,
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff2'
}
},
{
test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i,
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
},
// load these fonts normally, as files:
{
test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i,
loader: 'file-loader'
}
]
},
plugins: [
new AureliaPlugin(),
new ProvidePlugin({
'Promise': 'bluebird'
}),
new ModuleDependenciesPlugin({
'aurelia-testing': ['./compile-spy', './view-spy'],
'aurelia-i18n': [{
name: 'locales/en/translation.json',
chunk: 'lang-en'
}, {
name: 'locales/pt/translation.json',
chunk: 'lang-pt'
}]
}),
new HtmlWebpackPlugin({
template: 'index.ejs',
minify: production ? {
removeComments: true,
collapseWhitespace: true
} : undefined,
metadata: {
// available in index.ejs //
title,
server,
baseUrl
}
}),
...when(extractCss, new ExtractTextPlugin({
filename: production ? '[contenthash].css' : '[id].css',
allChunks: true
})),
...when(production, new CopyWebpackPlugin([{
from: 'static/favicon.ico',
to: 'favicon.ico'
}])),
...when(analyze, new BundleAnalyzerPlugin())
]
});
The issue in the above code happens at
{
test: /\.json$/i,
loader: 'json-loader'
},
Which if you comment, lets the app compile without issues, I've searched but event though I've found similar problems to this one, I haven't found a working solution, if anyone has any suggestion in how I can solve this problem I would appreciate it.
Thanks in advance.
The reason it says unexpected token m is because the json-loader transforms your json into a javascript file which starts with module.exports = ...
Of course that is not valid json (json must always start with opening brace {), hence it nags about the "m" of "module".
In other words, this error is indicative of webpack trying to apply json-loader twice in a row. Changing json-loader to raw-loader should get rid of webpack's wrapper javascript and pass the json as-is to whatever other plugin might be trying to load it as raw json.
Here's a related issue that might help you get this cleared up:
https://github.com/webpack-contrib/json-loader/issues/13
I didn't have the loader set in my script and i fixed it by adding this to my headers. In my case this was just a API call to my Smart lighting system
const body =
{
"device": "2B:5A:D4:AD",
"model": "H619E",
"cmd": {
"name": "turn",
"value": "off"
}
}
let res = await fetch('https://developer-api.govee.com/v1/devices/control', {
method: 'put',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
You can remove this error from the backend side by just send response in valid JSON format. So automatically error will go from the frontend side.
Just add a line in the backend where send response.
return res.status(201).json({
message: 'Success',
})
Related
I'm trying to create JS widgets from my existing react app. So currently I have an app that looks something like this
-src
- config
- components
- containers
- lib
- assets
- widgets
- widgetOne
- widgetTwo
- components
- widget.js
- index.js
- index.js
- index.html
So, I want directories in the widgets directories to be self contained apps that I can break out into a separate js file and a client can just add the js script into their page in a script tag.
I've come close but still facing a few issues. Also, I wanted to see if someone had experience doing this following a better pattern.
Right now I'm using webpack to do this splitting. I'm just defining /src/widgets/widgetOne/index.js as an entry point and perfectly creates a separate file.
Here is my webpack:
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 BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const htmlWebpackPlugin = new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html",
hash: 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: {
main: [ "#babel/polyfill", "./src/index.js"],
widgetOne: ["./src/widgets/widgetOne/index.js"]
},
output: {
publicPath: appConstants().BASENAME ? JSON.parse(appConstants().BASENAME) : '/'
},
optimization: {
splitChunks: {
chunks: 'all'
}
},
plugins: [
htmlWebpackPlugin,
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/),
new BundleAnalyzerPlugin({
analyzerMode: 'disabled',
generateStatsFile: true,
statsOptions: { source: false }
}),
new webpack.DefinePlugin({
'process.env': appConstants()
}),
new webpack.EnvironmentPlugin(['NODE_ENV'])
],
devServer: {
historyApiFallback: true,
port: 9090
}
};
module.exports = webpackConfig;
The problem I have now is while I get the widgetOne.js:
1) I end up with a vendor~widgetOne.js file that I also need to include to make the widgetOne app to work.
2) The widgetOne.js also gets added to my index.html file for my main app which I do not want.
Is there a way to configure webpack properly to make this work?
So, this is the solution I came up with that seems to work. I still don't know if this is the best approach but it' the only one I was able to get to work for me.
I decided to build the widgets as a different environment process and and modify the webpack configs based on that environment.
So the package.json I add this line under scritps:
"build-widgets": "cross-env NODE_ENV=plugins webpack --mode development",
And I added this section to the end of my webpack.config.js file:
// Override webpack configs when building plugins
if ( process.env.NODE_ENV === 'plugins') {
webpackConfig.entry = {
widgetOne: [ "#babel/polyfill", "./src/plugins/widgetOne/index.js"]
}
webpackConfig.output = {
publicPath: appConstants().DS_BASENAME ? JSON.parse(appConstants().DS_BASENAME) : '/',
path: __dirname + '/dist/widgets',
library: 'MyApp',
libraryTarget: 'umd',
umdNamedDefine: true
}
}
Alternatively, I could have just added a second webpack.config.js exclusively to deal with my widgets build. In my case I didn't feel the need for it just yet but it's something to be considered for sure, just for the sake of keeping configs separate.
I am attempting to migrate to Webpack 2 from 1 and am receiving quite a few errors. I managed to get rid of some errors but am still receiving the following:
$ node scripts/start.js
(node:42015) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
configuration.resolve has an unknown property 'fallback'. These properties are valid:
object { alias?, aliasFields?, cachePredicate?, descriptionFiles?, enforceExtension?, enforceModuleExtension?, extensions?, fileSystem?, mainFields?, mainFiles?, moduleExtensions?, modules?, plugins?, resolver?, symlinks?, unsafeCache?, useSyncFileSystemCalls? }
(node:42015)
DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
My webpack config is below
var autoprefixer = require('autoprefixer');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ManifestPlugin = require('webpack-manifest-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var url = require('url');
var paths = require('./paths');
var getClientEnvironment = require('./env');
function ensureSlash(path, needsSlash) {
var hasSlash = path.endsWith('/');
if (hasSlash && !needsSlash) {
return path.substr(path, path.length - 1);
} else if (!hasSlash && needsSlash) {
return path + '/';
} else {
return path;
}
}
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
var homepagePath = require(paths.appPackageJson).homepage;
var homepagePathname = homepagePath ? url.parse(homepagePath).pathname :
%PUBLIC_PATH%xyz.
var publicUrl = ensureSlash(homepagePathname, false);
var env = getClientEnvironment(publicUrl);
// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if (env['process.env'].NODE_ENV !== '"production"') {
throw new Error('Production builds must have NODE_ENV=production.');
}
module.exports = {
bail: true,
entry: [
require.resolve('./polyfills'),
paths.appIndexJs
],
output: {
// The build folder.
path: paths.appBuild,
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
filename: 'assets/static/js/[name].js',
chunkFilename: 'assets/static/js/[name].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: publicPath
},
resolve: {
extensions: ['.js', '.json', '.jsx'],
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'
}
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc,
enforce: 'pre'
},
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.css$/,
/\.json$/,
/\.svg$/
],
loader: 'url',
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
},
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
loader: 'babel',
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', 'css?importLoaders=1!postcss')
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
},
// JSON is not enabled by default in Webpack but both Node and Browserify
// allow it implicitly so we also enable it.
{
test: /\.json$/,
loader: 'json'
},
// "file" loader for svg
{
test: /\.svg$/,
loader: 'file',
options: {
name: 'static/media/[name].[hash:8].[ext]'
}
}
]
},
plugins: [
// Makes the public URL available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In production, it will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin({
PUBLIC_URL: publicUrl
}),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env),
// This helps ensure the builds are consistent if source hasn't changed:
new webpack.optimize.OccurrenceOrderPlugin(),
// Try to dedupe duplicated modules, if any:
new webpack.optimize.DedupePlugin(),
// Minify the code.
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true, // React doesn't support IE8
warnings: false
},
mangle: {
screw_ie8: true
},
output: {
comments: false,
screw_ie8: true
}
}),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin('assets/static/css/[name].css'),
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without
// having to parse `index.html`.
new ManifestPlugin({
fileName: 'asset-manifest.json'
})
],
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};
And my start.js is here https://pastebin.com/ENRYKUgL
Any help would be greatly appreciated.
fallback is an option of ExtractTextPlugin, perhaps try to define with the new use: { //.. } notation rather than query string notation. This may not be perfect but should get you started...
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{ loader: 'css-loader', options: {importLoaders: 1}},
{ loader: 'postcss-loader' }
]
})
}
On a side note, you shouldn't need OccurrenceOrderPlugin or DedupePlugin in Webpack 2 as they are included by default
Is there a way to prevent in React.js, raw HTML display before the CSS stylesheets are completely loaded. I'm using Webpack, Semantic-UI (react version) and React.js.
Is there an equivalent of ng-cloak (angular) in React ?
Here's the content of my webpack config file :
const webpack = require('webpack')
const ManifestPlugin = require('webpack-manifest-plugin')
const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const DEBUG = process.env.NODE_ENV !== 'production'
const plugins = [
new webpack.DefinePlugin({
'process.env.NODE_ENV': `"${process.env.NODE_ENV}"`
})
]
const assetsDir = process.env.ASSETS_DIR
const assetMapFile = process.env.ASSETS_MAP_FILE
const outputFile = DEBUG ? '[name].js' : '[name].[chunkhash].js'
if (!DEBUG) {
plugins.push(new ManifestPlugin({
fileName: assetMapFile
}))
plugins.push(new webpack.optimize.UglifyJsPlugin({ minimize: true }))
}
const config = {
entry: {
bundle: ['babel-polyfill', './src/client/index.jsx']
},
module: {
noParse: [],
loaders: [
{ test: /\.json$/, loader: 'json' },
{ test: /\.css$/, loader: 'style!css' },
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /(node_modules|bower_components)/,
query: {
cacheDirectory: DEBUG
}
},
{test:/.svg$/,loader:'url-loader',query:{mimetype:'image/svg+xml',
name:'/semantic/themes/default/assets/fonts/icons.svg'}},
{test:/.woff$/,loader:'url-loader',query:{mimetype:'application/font-woff',
name:'/semantic/themes/default/assets/fonts/icons.woff'}},
{test:/.woff2$/,loader:'url-loader',query:{mimetype:'application/font-woff2',
name:'/semantic/themes/default/assets/fonts/icons.woff2'}},
{test:/.[ot]tf$/,loader:'url-loader',query:{mimetype:'application/octet-stream',
name:'/semantic/themes/default/assets/fonts/icons.ttf'}},
{test:/.eot$/,loader:'url-loader',query:{mimetype:'application/vnd.ms-fontobject',
name:'/semantic/themes/default/assets/fonts/icons.eot'}},
{ test: /\.png/, loader: "url-loader?limit=100000&minetype=image/png" },
{ test: /\.jpg/, loader: "file-loader" }
]
},
node: {
fs: "empty"
},
resolve: {
alias: {
"semantic-ui" : path.resolve( __dirname, "../semantic/dist/semantic.min.css")
},
extensions: ['', '.js', '.jsx', ".css"]
},
plugins,
output: {
filename: outputFile,
path: DEBUG ? '/' : assetsDir,
publicPath: '/assets/'
}
}
if (DEBUG) {
config.devtool = '#inline-source-map'
} else if (process.env.NODE_ENV === 'production') {
config.devtool = 'source-map'
}
module.exports = config
I got this error when I try to load my css from my component :
Cannot find module '/semantic/dist/semantic.min.css'
and the module exists.
I tried the exact same configuration without Webpack and import from component worked.
This is not the correct setup for a production deploy.
By default, Webpack turns your CSS into Javascript code that injects CSS tags in the page. This allows for hot CSS reloading. It's only appropriate for the development environment, obviously. You should be using this default behavior in dev, and should not be using it in production.
In production, you need to build a separate CSS file and load it normally with a <style> tag in your production HTML code. To tell Webpack to pull that out into a file, use the ExtractTextPlugin, which your code requires but never uses.
You should maintain two Webpack config files, one for development which doesn't extract text (and doesn't minify/uglify, etc), and one for production, which correctly minifies, hashes names, extracts text, etc.
I'm getting an error when trying to run my webpack for production.
ERROR in js/main.21dbce548a76ffc14cfb.js from UglifyJs
SyntaxError: Unexpected token: operator (>) [./~/tmi.js/lib/utils.js:3,0][js/main.21dbce548a76ffc14cfb.js:3529,20]
utils.js:3,0 (which is the same as in my minified js) is:
// Return the second value if the first value is undefined..
get: (obj1, obj2) => { return typeof obj1 === "undefined" ? obj2 : obj1; },
So I assume from that the error is thrown because it's reading ES6 but it doesn't understand ES6? (The arrow function)
I don't see what's going wrong here, this is my webpack.config.js
// changed some loader syntax after reading
// https://webpack.js.org/how-to/upgrade-from-webpack-1/
const path = require(`path`);
const webpack = require(`webpack`);
const {UglifyJsPlugin} = webpack.optimize;
const CopyWebpackPlugin = require(`copy-webpack-plugin`);
const ExtractTextWebpackPlugin = require(`extract-text-webpack-plugin`);
const configHtmls = require(`webpack-config-htmls`)();
const extractCSS = new ExtractTextWebpackPlugin(`css/style.css`);
// change for production build on different server path
const publicPath = `/`;
// hard copy assets folder for:
// - srcset images (not loaded through html-loader )
// - json files (through fetch)
// - fonts via WebFontLoader
const copy = new CopyWebpackPlugin([{
from: `./src/assets`,
to: `assets`
}], {
ignore: [ `.DS_Store` ]
});
const config = {
entry: [
`./src/css/style.css`,
`./src/js/script.js`
],
resolve: {
// import files without extension import ... from './Test'
extensions: [`.js`, `.jsx`, `.css`]
},
output: {
path: path.join(__dirname, `server`, `public`),
filename: `js/[name].[hash].js`,
publicPath
},
devtool: `sourcemap`,
module: {
rules: [
{
test: /\.css$/,
loader: extractCSS.extract([
{
loader: `css`,
options: {
importLoaders: 1
}
},
{
loader: `postcss`
}
])
},
{
test: /\.html$/,
loader: `html`,
options: {
attrs: [
`audio:src`,
`img:src`,
`video:src`,
`source:srcset`
] // read src from video, img & audio tag
}
},
{
test: /\.(jsx?)$/,
exclude: /node_modules/,
use: [
{
loader: `babel`
},
{
loader: `eslint`,
options: {
fix: true
}
}
]
},
{
test: /\.(svg|png|jpe?g|gif|webp)$/,
loader: `url`,
options: {
limit: 1000, // inline if < 1 kb
context: `./src`,
name: `[path][name].[ext]`
}
},
{
test: /\.(mp3|mp4)$/,
loader: `file`,
options: {
context: `./src`,
name: `[path][name].[ext]`
}
}
]
},
plugins: [
extractCSS,
copy
]
};
if(process.env.NODE_ENV === `production`){
//image optimizing
config.module.rules.push({
test: /\.(svg|png|jpe?g|gif)$/,
loader: `image-webpack`,
enforce: `pre`
});
config.plugins = [
...config.plugins,
new UglifyJsPlugin({
sourceMap: true, // false returns errors.. -p + plugin conflict
comments: false
})
];
}
config.plugins = [...config.plugins, ...configHtmls.plugins];
module.exports = config;
OP's error is from UglifyJs, as is solved in the accepted answer, some people to this page may get the error from babel, in which case, fix it with: add "presets": ["es2015"] either to the options.presets section of babel-loader, or to .babelrc.
UglifyJs2 has a Harmony branch which accepts ES6 syntax to be minified. At this moment, you need to create a fork of webpack and point webpack to that fork.
I recently answered a couple of similar questions. Please have a look at #38387544 or #39064441 for detailed instructions.
In my case I was using webpack version 1.14
I got help from git ref
steps:
install yarn add uglifyes-webpack-plugin (and removed yarn remove uglifyjs-webpack-plugin)
then install yarn add uglify-js-es6
In webpack.config.js file change new webpack.optimize.UglifyJsPlugin to
new UglifyJsPlugin
then I was able to build. Thanks
I'm trying to develop a react isomorphic app, and i've recently came up with the webpack-isomorphic-tools npm package.
I've tried to follow the documentation but unfortunately the images and style files doesn't get recognized, and not added to the webpack-assets.json file.
Up until now I've used this method:
if(process.env.BROWSER){
include('./style.scss');
}
But I understood webpack-isomorphic-tools is more beneficial.
for scss and other style files this is the error i get when running the server:
[webpack-isomorphic-tools] [debug] requiring ./shared/Root.scss
[webpack-isomorphic-tools] [error] asset not found: ./shared/Root.scss
for image files no errors are shown during the build, since no images are detected on the build. here is the webpack-assets.js:
{
"javascript": {
"main": "/build/bundle.js"
},
"styles": {},
"assets": {}
}
Relevant code:
webpack-isomorphic-tools-config.js:
var webpack_isomorphic_tools_plugin = require('webpack-isomorphic-tools/plugin');
module.exports =
{
debug: true,
webpack_assets_file_path : 'public/build/webpack-assets.json',
webpack_stats_file_path : 'public/build/webpack-stats.json',
assets:
{
images:
{
extensions: ['png', 'jpg', 'gif', 'ico', 'svg']
},
fonts:
{
extensions: ['woff', 'woff2', 'eot', 'ttf']
},
styles:
{
extensions: ['scss', 'less', 'css'],
filter(module, regular_expression, options, log)
{
if (options.development)
{
// In development mode there's Webpack "style-loader",
// which outputs `module`s with `module.name == asset_path`,
// but those `module`s do not contain CSS text.
//
// The `module`s containing CSS text are
// the ones loaded with Webpack "css-loader".
// (which have kinda weird `module.name`)
//
// Therefore using a non-default `filter` function here.
//
return webpack_isomorphic_tools_plugin.style_loader_filter(module, regular_expression, options, log)
}
// In production mode there will be no CSS text at all
// because all styles will be extracted by Webpack Extract Text Plugin
// into a .css file (as per Webpack configuration).
//
// Therefore in production mode `filter` function always returns non-`true`.
},
// How to correctly transform kinda weird `module.name`
// of the `module` created by Webpack "css-loader"
// into the correct asset path:
path: webpack_isomorphic_tools_plugin.style_loader_path_extractor,
// How to extract these Webpack `module`s' javascript `source` code.
// Basically takes `module.source` and modifies its `module.exports` a little.
parser: webpack_isomorphic_tools_plugin.css_loader_parser
}
}
}
index.js (looks a lot like the one in the documentation):
'use strict';
var path = require('path');
require('babel-register');
require('babel-polyfill');
require('app-module-path').addPath(path.join(__dirname,'shared'));
global._development_ = false
if (process.env.NODE_ENV !== 'production'){
global._development_ = true;
}
var Webpack_isomorphic_tools = require('webpack-isomorphic-tools');
// this must be equal to your Webpack configuration "context" parameter
var project_base_path = path.resolve(__dirname);
// this global variable will be used later in express middleware
global.webpack_isomorphic_tools = new Webpack_isomorphic_tools(require('./webpack-isomorphic-tools-config'))
// enter development mode if needed
// (you may also prefer to use a Webpack DefinePlugin variable)
.development(!(process.env.NODE_ENV === 'production'))
// initializes a server-side instance of webpack-isomorphic-tools
// (the first parameter is the base path for your project
// and is equal to the "context" parameter of you Webpack configuration)
// (if you prefer Promises over callbacks
// you can omit the callback parameter
// and then it will return a Promise instead)
.server(project_base_path, function()
{
// webpack-isomorphic-tools is all set now.
// here goes all your web application code:
// (it must reside in a separate *.js file
// in order for the whole thing to work)
require('./server/server')
});
webpack.dev.js (webpack-dev-server config):
var path = require('path');
var webpack = require('webpack');
var Webpack_isomorphic_tools_plugin = require('webpack-isomorphic-tools/plugin')
var webpack_isomorphic_tools_plugin =
// webpack-isomorphic-tools settings reside in a separate .js file
// (because they will be used in the web server code too).
new Webpack_isomorphic_tools_plugin(require('./webpack-isomorphic-tools-config'))
// also enter development mode since it's a development webpack configuration
// (see below for explanation)
.development();
module.exports = {
context: __dirname,
entry: ['webpack-dev-server/client?http://127.0.0.1:8080/',
'webpack/hot/only-dev-server',
'./client/index.jsx'],
resolve: {
modulesDirectories: ['node_modules', 'shared'],
extensions: ['', '.js', '.jsx']
},
output: {
path: path.join(__dirname, 'public', 'build'),
filename: 'bundle.js',
publicPath: "/build/"
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot', 'babel']
},
{
test: /\.css$/,
loader: "style-loader!css-loader!autoprefixer-loader"
},
{
test: /\.less$/,
loader: "style-loader!css-loader!autoprefixer-loader!less-loader"
},
{
test: /\.scss$/,
loader: "style-loader!css-loader!autoprefixer-loader!sass-loader"
},
{
test: webpack_isomorphic_tools_plugin.regular_expressions['images'],
loader: "url-loader?limit=10240"
},
{
test: webpack_isomorphic_tools_plugin.regular_expression['fonts'],
loader: "url-loader?limit=10240"
}
]
},
plugins: [
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true),
NODE_ENV: JSON.stringify( process.env.NODE_ENV || 'development' )
}
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
webpack_isomorphic_tools_plugin
],
devtool: 'inline-source-map',
devServer: {
hot: true,
proxy: {
'*': 'http://127.0.0.1:' + (process.env.PORT || 3000)
},
host: '127.0.0.1'
}
};
webpack.config.js:
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var Webpack_isomorphic_tools_plugin = require('webpack-isomorphic-tools/plugin')
var webpack_isomorphic_tools_plugin =
// webpack-isomorphic-tools settings reside in a separate .js file
// (because they will be used in the web server code too).
new Webpack_isomorphic_tools_plugin(require('./webpack-isomorphic-tools-config'));
module.exports = {
context: __dirname,
entry: ['./client/index.jsx'],
resolve: {
modulesDirectories: ['node_modules', 'shared'],
extensions: ['', '.js', '.jsx']
},
output: {
path: path.join(__dirname, 'public', 'build'),
filename: 'bundle.js',
publicPath: "/build"
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot', 'babel']
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader")
},
{
test: /\.less$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader!less-loader")
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!autoprefixer-loader!sass-loader")
},
{
test: /\.gif$/, loader: "url-loader?limit=10000&mimetype=image/gif"
},
{
test: /\.jpg$/, loader: "url-loader?limit=10000&mimetype=image/jpg"
},
{
test: /\.png$/, loader: "url-loader?limit=10000&mimetype=image/png"
},
{
test: /\.svg/, loader: "url-loader?limit=26000&mimetype=image/svg+xml"
},
{
test: /\.(woff|woff2|ttf|eot)/, loader: "url-loader?limit=1&name=/[hash].[ext]"
}
]
},
plugins: [
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true),
NODE_ENV: JSON.stringify( process.env.NODE_ENV || 'development' )
}
}),
new ExtractTextPlugin("bundle.css")
]
};
If more code is required, I'd be happy to give it, thanks!