I am trying to create an app in Electron which uses React, Webpack 2 Sharp and Electron.
I just added Sharp (https://github.com/lovell/sharp) and Webpack is adamantly trying to build Sharp but I don't think it should be (I could be wrong and if so, how would I get these files to load)?
I get the following stdout:
WARNING in ./~/sharp/lib/constructor.js
Module not found: Error: Can't resolve '../vendor/lib/versions.json' in '/Users/andy/Development/image-browser/node_modules/sharp/lib'
@ ./~/sharp/lib/constructor.js 23:15-53
@ ./~/sharp/lib/index.js
@ ./app/src/utils/getImage.js
@ ./app/src/components/Images/image.js
@ ./app/src/components/Images/index.js
@ ./app/src/App.js
@ ./app/src/entry.js
WARNING in ./~/sharp/lib/icc/sRGB.icc
Module parse failed: /Users/andy/Development/image-browser/node_modules/sharp/lib/icc/sRGB.icc Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
@ ./~/sharp/lib ^\.\/.*$
@ ./~/sharp/lib/index.js
@ ./app/src/utils/getImage.js
@ ./app/src/components/Images/image.js
@ ./app/src/components/Images/index.js
@ ./app/src/App.js
@ ./app/src/entry.js
WARNING in ./~/sharp/lib/icc/cmyk.icm
Module parse failed: /Users/andy/Development/image-browser/node_modules/sharp/lib/icc/cmyk.icm Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
@ ./~/sharp/lib ^\.\/.*$
@ ./~/sharp/lib/index.js
@ ./app/src/utils/getImage.js
@ ./app/src/components/Images/image.js
@ ./app/src/components/Images/index.js
@ ./app/src/App.js
@ ./app/src/entry.js
ERROR in ./~/sharp/build/Release/sharp.node
Module parse failed: /Users/andy/Development/image-browser/node_modules/sharp/build/Release/sharp.node Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
@ ./~/sharp/lib/constructor.js 8:14-52
@ ./~/sharp/lib/index.js
@ ./app/src/utils/getImage.js
@ ./app/src/components/Images/image.js
@ ./app/src/components/Images/index.js
@ ./app/src/App.js
@ ./app/src/entry.js
webpack.config.js
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
watch: true,
target: 'electron',
entry: './app/src/entry.js',
devtool: 'source-map',
output: {
path: __dirname + '/app/build',
publicPath: 'build/',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
include: /\/app\/src/,
// exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'env',
'react'
]
}
}
},
// {
// test: /\.node$/,
// use: {
// loader: 'node-loader'
// }
// },
{
test: /\.(sass|scss)$/,
include: /\/app\/src/,
// exclude: /(node_modules)/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
},
{
test: /\.(png|jpg|gif|svg)$/,
include: /\/app\/src/,
// exclude: /(node_modules)/,
use: {
loader: 'file-loader',
query: {
name: '[name].[ext]?[hash]'
}
}
}
]
},
plugins: [
new ExtractTextPlugin({
filename: 'bundle.css',
disable: false,
allChunks: true
})
]
}
My babel config (extracted from package.json):
"babel": {
"retainLines": true,
"presets": [
[
"env",
{
"targets": {
"electron": 1.6,
"node": 7.9
},
"modules": false,
"debug": true
}
],
"es2015",
"es2016",
"es2017"
]
},
Any ideas?
I have successfully got this working and the following is a mirror of the comment I added to this Github issue: https://github.com/lovell/sharp/issues/794
The key was finding this article: http://jlongster.com/Backend-Apps-with-Webpack--Part-I#p28 (thanks @jlongster).
My webpack.config.js looks like the following:
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const path = require('path');
const fs = require('fs');
// FROM: http://jlongster.com/Backend-Apps-with-Webpack--Part-I#p28
const nodeModules = {};
fs.readdirSync('node_modules')
.filter(item => ['.bin'].indexOf(item) === -1) // exclude the .bin folder
.forEach((mod) => {
nodeModules[mod] = 'commonjs ' + mod;
});
module.exports = {
watch: true,
target: 'electron',
entry: ['babel-polyfill', './app/src/entry.js'],
devtool: 'source-map',
externals: nodeModules,
output: {
path: __dirname + '/app/build',
publicPath: 'build/',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'app/src'),
use: {
loader: 'babel-loader',
options: {
presets: [
'env',
'react'
]
}
}
},
{
test: /\.(sass|scss)$/,
include: path.resolve(__dirname, 'app/src'),
use: [
'style-loader',
'css-loader',
'sass-loader',
]
},
{
test: /\.(png|jpg|gif|svg)$/,
include: path.resolve(__dirname, 'app/src'),
use: {
loader: 'file-loader',
query: {
name: '[name].[ext]?[hash]'
}
}
}
]
},
plugins: [
new ExtractTextPlugin({
filename: 'bundle.css',
disable: false,
allChunks: true
})
]
}
TL;DR
Use this to get a list of ALL your node modules:
const nodeModules = {};
fs.readdirSync('node_modules')
.filter(item => ['.bin'].indexOf(item) === -1 ) // exclude the .bin folder
.forEach((mod) => {
nodeModules[mod] = 'commonjs ' + mod;
});
and hand the nodeModules variable to Webpack's externals key:
externals: nodeModules,
Alternatively, you could use one of the Ignore Module Webpack plugins but I have not tried that myself.