Load static JSON at runtime in webpack build - javascript

I have built a tiny webapp with vue-cli. Now I have a JSON configuration file that has to be loaded at runtime, because the JSON will be regularly replaced on the production server.
I think I'm on the right track with:
module.exports = {
configureWebpack: {
module: {
rules: [
{
test: /\.json$/,
loader: 'file-loader',
exclude: '/node_modules',
options: {
name: '[name].[ext]'
}
}
],
},
},
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
}
But I get this error when I run npm run build:
Module parse failed: Unexpected token e in JSON at position 0 while parsing near 'export default __web...'
Any ideas on how to solve this?

Related

Invalid or unexpected token loading css file using webpack in react project

I have a react project that uses styled components, and I'm trying to include a CSS file as part of react-image-gallery
I followed the steps to include css-loader and style-loader in my project and tried importing the file like this
import 'react-image-gallery/styles/css/image-gallery.css
and included the following in Webpack config rules
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
}
When running the server I'm getting the below error message
SyntaxError: Invalid or unexpected token
(function (exports, require, module, __filename, __dirname) { #charset "UTF-8";
in the above CSS file
From some googling, I understood that this is because the CSS file is included as a JS file by Webpack. But isn't that how it is supposed to be?
Addition info: I have a server side rendered app.
What am I doing wrong?
Update:
My rules look like this
A rules.ts file
import webpack from 'webpack'
const ts: webpack.RuleSetRule = {
test: /^(?!.*\.spec\.tsx?$).*\.tsx?$/,
exclude: /node_modules/,
use: ['babel-loader'],
}
const img: webpack.RuleSetRule = {
test: /\.(png|jpe?g|gif|svg)$/,
use: 'file-loader',
}
const css: webpack.RuleSetRule = {
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
}
export default {
client: {
ts,
img,
css,
},
server: {
ts,
css,
img: { ...img, use: [{ loader: 'file-loader', options: { emitFile: false } }] },
},
}
A config file that has the following
const config: webpack.Configuration = {
context: path.join(__dirname, '../../src/client'),
resolve: {
...resolve.client,
alias: { 'react-dom': '#hot-loader/react-dom' },
},
devtool: false,
entry: {
main: ['./index.tsx'],
},
mode: 'development',
module: {
rules: [rules.client.ts, rules.client.img, rules.client.css],
},
output: output.client,
plugins: [
...plugins,
...developmentPlugins,
new ForkTsCheckerWebpackPlugin({
tsconfig: path.join(__dirname, '../../tsconfig.fork-ts-checker-webpack.plugin.json'),
}),
new CleanWebpackPlugin({
cleanAfterEveryBuildPatterns: ['!webpack.partial.html', '!favicon.ico'],
}),
],
}
We had 4 co-workers stuck on an issue like that.
Actually, we had a plugin "nodemon-webpack-plugin", which we configured for webpack.
This plugin tried to execute files like .css as java-script files.
We finally removed this plugin, because we had an up and running mon already.

MQTT.js and Webpack - "WS is not a constructor"

I am trying to bundle one of our microservices which is using MQTT.js and I am struggling with really strange issue.
It is working fine without bundling, so ws is available in node_modules.
Stuff which I think matters:
error:
TypeError: WS is not a constructor
at WebSocketStream (dist/index.js:159329:16)
at createWebSocket (dist/index.js:147450:10)
at Object.buildBuilderBrowser (dist/index.js:147476:10)
at MqttClient.wrapper [as streamBuilder] (dist/index.js:147937:36)
at MqttClient._setupStream (dist/index.js:146471:22)
at new MqttClient (dist/index.js:146452:8)
at Function.connect (dist/index.js:147940:10)
webpack config:
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { NODE_ENV = 'production' } = process.env;
module.exports = {
entry: { index: './src/index.ts' },
mode: NODE_ENV,
target: 'node',
watch: NODE_ENV === 'development',
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
resolve: {
extensions: ['.ts', '.js'],
},
node: {
__dirname: false,
},
module: {
rules: [
{
test: /\.ts$/,
use: [{ loader: 'ts-loader', options: { transpileOnly: true } }],
},
{
test: /(\.md|\.map)$/,
loader: 'null-loader',
},
],
},
};
Function where it happens:
createMqttClient(): MqttClient {
return mqtt.connect(this.mqttOptions.url, { ...this.mqttOptions.options });
}
The url is like: ssl://url-to-our-mqtt
Can anybody help please?
I also ran into same issue.
The problem for me was that I used
plugins: [
new webpack.NormalModuleReplacementPlugin(/^mqtt$/, "mqtt/dist/mqtt.js"),
],
in webpack.config.js order to fix the shebang error that comes with mqtt.js since it is a CLI tool.
Then instead I have used
{
test: [
/node_modules[/\\]mqtt[/\\]mqtt.js/,
/node_modules[/\\]mqtt[/\\]bin[/\\]sub.js/,
/node_modules[/\\]mqtt[/\\]bin[/\\]pub.js/,
],
loader: 'shebang-loader'
},
And my problem was fixed. Do you also use mqtt/dist/mqtt.js instead of mqtt in your imports or if you do something similar to mine, the shebang-loader rule I have posted above might solve your problem.
I experienced the same with Amazon aws-iot-device-sdk-js and Microsoft azure-iot-device-mqtt which both include mqtt.
The initial issue is the build error:
ERROR in ./node_modules/mqtt/mqtt.js Module parse failed: Unexpected character '#' (1:0)
This error is caused by the package mqtt. Three files (mqtt.js, pub.js and sub.js) contain a shebang line
#!/usr/bin/env node
The solution using module replacement suggested some places
plugins: [
new webpack.NormalModuleReplacementPlugin(/^mqtt$/, "mqtt/dist/mqtt.js"),
],
unfortunately changes the build error with the run time error
TypeError: WS is not a constructor
As mentioned in other answers, webpack can be configured (https://webpack.js.org/concepts/loaders/) to use the shebang loader (https://www.npmjs.com/package/shebang-loader)
TL;DR
Install shebang-loader
npm install shebang-loader --save
In webpack.config.js use the loader
module.exports = {
...
module: {
rules: [
{
test:
[
/.*mqtt\.js$/,
/.*sub\.js$/,
/.*pub\.js$/
],
use: 'shebang-loader'
}
]
}
}

Uncaught SyntaxError: Unexpected token > when loading Phonegap app on Android phone

--- UPDATE ---
Error disappeared when setting NODE_ENV=production before my webpack build-step. I still don't know what the underlying cause for this issue was.
--- END UPDATE ---
I have made a Phonegap app using Webpack. The app works fine on iOS and other Android devices, but it crashes on a Huawei Honor H60-L04 with Android 4.4.2. It crashes on load, showing this error:
Uncaught SyntaxError: Unexpected token >
By adding/removing all scripts loaded in index.html one by one, I have isolated the problem to exist in the dist/build.js file. That is the resulting js file from Webpack build, with all the app logic inside. Is there some webpack config mistake causing this issue? And why is only this device getting the error?
If relevant, I am using Vue.js and Framework7 to develop the app, and Phonegap Build to build it.
--- UPDATE --- :
When remote debugging the console says the error is at line 85 in index.html, but the index.html is not that long. Guessing that line number reports that way because dynamic things are added to the html-file when trying to load script.
My entire .babelrc file:
{
"plugins": ["transform-es2015-shorthand-properties"]
}
My entire Webpack config file:
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
performance: {
hints: false
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
sass: "vue-style-loader!css-loader!sass?indentedSyntax"
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue',
'Framework7Vue': path.join(__dirname, '/node_modules/framework7-vue/dist/framework7-vue.min.js')
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
--- END UPDATE ---

Setup webpack with server side rendering to load Sass files in asp.net core project

I'm using a Yeoman project template called "aspnetcore-spa", which is an ASP.net core 1 template working in conjunction with major SPA frameworks (Angular2 and React).
I created a project with Angular2.The biolerplate's code works fine and there is no problem. Once I add Sass loader to webpack.config.js and make a reference to the Sass file from any angular file.
In webpack.config.js :
var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');
var merge = require('webpack-merge');
var allFilenamesExceptJavaScript = /\.(?!js(\?|$))([^.]+(\?|$))/;
// Configuration in common to both client-side and server-side bundles
var sharedConfig = {
resolve: { extensions: [ '', '.js', '.ts' ] },
output: {
filename: '[name].js',
publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
loaders: [
{ test: /\.ts$/, include: /ClientApp/, loader: 'ts', query: { silent: true } },
{ test: /\.scss$/,include:/ClientApp/, loaders: ["style", "css", "sass"] },
{ test: /\.html$/,include: /ClientApp/, loader: 'raw' },
{ test: /\.css$/, loader: 'to-string!css' },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url', query: { limit: 25000 } }
]
}
};
// Configuration for client-side bundle suitable for running in browsers
var clientBundleOutputDir = './wwwroot/dist';
var clientBundleConfig = merge(sharedConfig, {
entry: { 'main-client': './ClientApp/boot-client.ts' },
output: { path: path.join(__dirname, clientBundleOutputDir) },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
])
});
// Configuration for server-side (prerendering) bundle suitable for running in Node
var serverBundleConfig = merge(sharedConfig, {
entry: { 'main-server': './ClientApp/boot-server.ts' },
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, './ClientApp/dist')
},
target: 'node',
devtool: 'inline-source-map',
externals: [nodeExternals({ whitelist: [allFilenamesExceptJavaScript] })] // Don't bundle .js files from node_modules
});
module.exports = [clientBundleConfig, serverBundleConfig];
In my component :
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-wine',
template: require('./wine.component.html'),
styles: require('./wine.component.scss')
})
export class WineComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
I have already installed npm packages pertinent to sass loader :
npm install node-sass sass-loader --save-dev
I have checked the main-server.js file in wwwroot/dist folder which is the result of webpack bundling, I saw that the .scss file is loaded and they styles are processed correctly. Once I run the app though, shows this exception which is coming from the server side rendering side:
An unhandled exception occurred while processing the request.
Exception: Call to Node module failed with error: ReferenceError: window is not defined at E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:573:31 at E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:568:48 at module.exports (E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:590:69) at Object. (E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:526:38) at webpack_require (E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:20:30) at E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:501:22 at Object.module.exports (E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:506:3) at webpack_require (E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:20:30) at Object. (E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:129:25) at webpack_require (E:\Dev\MyApp\MyAppCore\src\MyApp.Web\ClientApp\dist\main-server.js:20:30)
It's obviously because of the webpack's server-side rendering, as it's running the code on Node.js side (through ASP.net Core's Javascript Services) and there is a code that is coupled with the DOM window object which is not valid on node.
Any clues?
I managed to fix the problem, here's the web.config.js bit:
(Notice the loaders for .scss files)
module: {
loaders: [
{ test: /\.ts$/, include: /ClientApp/, loader: 'ts', query: { silent: true } },
{ test: /\.scss$/,include:/ClientApp/, loaders: ["to-string", "css", "sass"] },
{ test: /\.html$/,include: /ClientApp/, loader: 'raw' },
{ test: /\.css$/, loader: 'to-string!css' },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url', query: { limit: 25000 } }
]
}
And in the Angular component I changed the styles to this :
(Passed an array of required css files rather than a single css file)
#Component({
selector: 'app-wine',
template: require('./wine.component.html'),
styles: [require('./wine.component.scss')]
})

webpack-dev-server acting weird

I've encountered a problem working with webpack-dev-server wherein the terminal output states that the bundle is valid, and when I request my app on my server (ie localhost), everything works as it should. When I request my app from another host, however, I am unable to load bundle.js, and I get a Network connection was lost error on Safari and a net::ERR_EMPTY_RESPONSE on Chrome. To explain further, if I go to http://url/public/bundle.js on my server, I get bundle.js, and if I try to do the same on my local machine, I get the errors. Here's my webpack.config.js file:
module.exports = {
entry: [
'./assets/jsx/modsoussi.jsx'
],
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
publicPath: 'http://modsoussi.xyz:8080/public/',
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules)/,
loader: 'babel',
query: {
presets: ['es2015','react'] // react preset is needed in this case to avoid
// unexpected token '<' error.
}
}
]
},
externals: {
'react':'React'
},
resolve: {
extensions: ['','.js','.jsx']
}
}

Categories

Resources