EDIT: I meant to say "whenever I make a change to main.js"
I'm new to electron, and have been taking a course on how to work with Electron together with React.
My project keeps crashing with the following alert whenever I make and save a change to main.js
This is my main.js file
// Main Process
const {
app,
BrowserWindow,
ipcMain,
Notification,
Menu,
Tray,
} = require("electron");
const path = require("path");
const isDev = !app.isPackaged;
const dockIcon = path.join(__dirname, "assets", "images", "react_app_logo.png");
const trayIcon = path.join(__dirname, "assets", "images", "react_icon.png");
// This is a window for our splash screen. Not a bad idea to have one before the app is ready.
function createSplashWindow() {
const win = new BrowserWindow({
width: 400,
height: 200,
frame: false,
backgroundColor: "white",
transparent: true,
webPreferences: {
nodeIntegration: false,
worldSafeExecuteJavaScript: true,
contextIsolation: true,
},
});
win.loadFile("splash.html");
return win;
}
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
backgroundColor: "white",
show: false,
webPreferences: {
nodeIntegration: false,
worldSafeExecuteJavaScript: true,
contextIsolation: true,
preload: path.join(__dirname, "preload.js"),
},
});
win.loadFile("index.html");
isDev && win.webContents.openDevTools();
return win;
}
if (isDev) {
require("electron-reload")(__dirname, {
electron: path.join(__dirname, "node_modules", ".bin", "electron"),
});
}
if (process.platform === "darwin") {
app.dock.setIcon(dockIcon);
}
let tray = null;
app.whenReady().then(() => {
const template = require("./utils/Menu").createTemplate(app);
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
tray = new Tray(trayIcon);
tray.setContextMenu(menu);
const splash = createSplashWindow();
const mainApp = createWindow();
mainApp.once("ready-to-show", () => {
// splash.destroy();
// mainApp.show();
// Should we get it out of the timeout probably?
setTimeout(() => {
splash.destroy();
mainApp.show();
}, 2000);
});
});
ipcMain.on("notify", (_, message) => {
new Notification({ title: "Notification", body: message }).show();
});
ipcMain.on("app-quit", () => {
app.quit();
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
And not sure if relevant, but this is my webpack.common.js file
const path = require("path");
const Dotenv = require("dotenv-webpack");
module.exports = {
mode: "development",
entry: "./src/js/index.tsx",
devtool: "inline-source-map",
target: "electron-renderer",
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
[
"#babel/preset-env",
{
targets: {
esmodules: true,
},
},
],
"#babel/preset-react",
],
},
},
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: [/\.s[ac]ss$/i, /\.css$/i],
use: [
// Creates `style` nodes from JS strings
"style-loader",
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader",
],
},
],
},
plugins: [new Dotenv()],
resolve: {
extensions: [".js", ".tsx", ".ts"],
},
output: {
filename: "app.js",
path: path.resolve(__dirname, "build", "js"),
},
};
Related
When I import the react component for the next SSR, it gives an import error, what could be the matter? I don't want to use type module in package.json
Maybe I made a mistake somewhere.....I will be very grateful for your help
babel.rc
{
"presets": [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript",
"#babel/register"
]
}
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const TerserWebpackPlugin = require("terser-webpack-plugin");
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { getGlobals } = require("./config/get-globals");
const isDev = process.env.NODE_ENV === "development";
const isProd = !isDev;
const globals = getGlobals();
const optimization = () => {
const config = {
splitChunks: {
chunks: "all",
},
};
if (isProd) {
config.minimizer = [
new CssMinimizerWebpackPlugin(),
new TerserWebpackPlugin(),
];
}
return config;
};
const ClientConfig = {
entry: path.join(__dirname, "src", "index.jsx"),
output: {
path: path.join(__dirname, "build"),
filename: "[name].[contenthash].js",
},
mode: 'development' === process.env.NODE_ENV ? 'development' : 'production',
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, "src", "public", "index_template.ejs"),
favicon: "src/public/favicon.ico",
alwaysWriteToDisk: true,
minify: {
collapseWhitespace: isProd,
},
inject: false,
templateParameters: (options) => {
const js = Object.keys(options.assets)
.filter((el) => /\.js$/.test(el))
.map((el) => "/" + el);
const css = Object.keys(options.assets)
.filter((el) => /\.css$/.test(el))
.map((el) => "/" + el);
return {
css,
js,
globals,
};
},
}),
new HtmlWebpackPlugin({
inject: false,
minify: false,
template: path.resolve(__dirname, "config", "render-stats.js"),
filename: path.join(__dirname, "config", "build-stats.json"),
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, "src", "public", "favicon.ico"),
to: path.resolve(__dirname, "build"),
},
],
}),
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: "ts-loader",
},
},
{
test: /\.(png|svg|jpg|gif|jpeg|ico)$/,
use: ["file-loader"],
},
{
test: /\.(ttf|woff|woff2|eot)$/,
use: ["file-loader"],
},
{
test: /\.xml$/,
use: ["xml-loader"],
},
{
test: /\.csv$/,
use: ["csv-loader"],
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
},
},
],
},
{
test: /\.ejs$/,
use: { loader: "ejs-compiled-loader", options: {} },
},
],
},
resolve: {
extensions: [".js", ".jsx", ".ejs", ".tsx", ".ts"],
},
devServer: {
port: 3007,
hot: isDev,
},
optimization: optimization(),
};
module.exports = [ClientConfig];
server.js
const express = require("express");
const fs = require("fs");
const path = require("path");
// create express application
const app = express();
// import App component
const { App } = require("../src/components/app.tsx");
app.use("*", (req, res) => {
let indexHTML = fs.readFileSync(path.resolve(__dirname, "../build/index.html"), {
encoding: "utf8"
});
// set header and status
res.contentType("text/html");
res.status(200);
return res.send(indexHTML);
});
// run express server on port 9000
app.listen("9000", () => {
console.log("Express server started at http://localhost:9000");
});
Error
import * as React from "react";
^^^^^^
SyntaxError: Cannot use import statement outside a module
Use this configuration for compile server filewebpack.server.config.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
entry: './src/server/index.js',
target: 'node',
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname, './dist/server'),
filename: 'server.js'
},
resolve : {
extensions : [".js",".jsx"],
},
module: {
rules: [
{
test: /\.jsx?/,
use: 'babel-loader'
}
]
}
};
I work with webpack 5. Pug works well - after autosave or cmd+S I get new version of page. And it doesn't work so with JS and SCSS: SCSS autosave works well but after cmd+S I get some old version of page(usually everytime the same). With JS both autosave and cmd+S return some old version of page. Can you help me to find a solution? Below I dropped webpack.config.js
const path = require("path");
const fs = require("fs");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const isDev = process.env.NODE_ENV === "development";
const isProd = !isDev;
const PATHS = {
src: path.join(__dirname, "./src"),
dist: path.join(__dirname, "./dist"),
};
const PAGES_DIR = `${PATHS.src}/`;
const PAGES = fs.readdirSync(PAGES_DIR).filter((fileName) => fileName.endsWith(".pug"));
const filename = (ext) => `[name].${ext}`;
const plugins = () => {
const basePlugins = [
...PAGES.map(
(page) =>
new HTMLWebpackPlugin({
template: `${PAGES_DIR}/${page}`,
filename: `./${page.replace(/\.pug/, ".html")}`,
})
),
new MiniCssExtractPlugin({
filename: `./css/${filename("css")}`,
}),
new CopyWebpackPlugin({
patterns: [
{ from: path.resolve(__dirname, "src/assets"), to: path.resolve(`${PATHS.dist}`) },
{ from: path.resolve(__dirname, "src/img"), to: path.resolve(`${PATHS.dist}/img/`) },
],
}),
];
return basePlugins;
};
module.exports = {
context: path.resolve(`${PATHS.src}`),
mode: "development",
entry: "./js/main.js",
output: {
filename: `./js/${filename("js")}`,
path: path.resolve(`${PATHS.dist}`),
publicPath: "",
clean: true,
},
devServer: {
historyApiFallback: true,
static: path.resolve(`${PATHS.dist}`),
open: true,
compress: true,
hot: true,
port: 3000,
},
optimization: {
splitChunks: {
chunks: "all",
},
},
plugins: plugins(),
devtool: isProd ? false : "source-map",
module: {
rules: [
{
test: /\.pug$/,
loader: "pug-loader",
},
{
test: /\.s[ac]ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
return path.relative(path.dirname(resourcePath), context) + "/";
},
},
},
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"],
},
},
},
"sass-loader",
],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.(?:|gif|png|jpg|jpeg|svg|webp)$/,
use: [
{
loader: "file-loader",
options: {
name: `./img/${filename("[ext]")}`,
},
},
],
},
{
test: /\.(?:|woff2)$/,
use: [
{
loader: "file-loader",
options: {
name: `./fonts/${filename("[ext]")}`,
},
},
],
},
],
},
};
I don't know what to write here. I described my problem above.
I can't figure out how to configure Image Minimizer Webpack Plugin so that images are converted to webp format if I use them in html.
This is not work using in html
img.image(src="./images/image.jpg?as=webp")
If I use images in css, then everything works.
div {
background: url("./file.jpg?as=webp");
}
This works.
I did everything according to the Documentation. I definitely missed something or didn't understand. Help me figure it out
Webpack config
const path = require("path");
const fs = require("fs");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const SVGSpritemapPlugin = require("svg-spritemap-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlBeautifyPlugin = require("#sumotto/beautify-html-webpack-plugin");
const miniSVGDataURI = require("mini-svg-data-uri");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
// Variables
const PATHS = {
src: path.join(__dirname, "../src"),
dist: path.join(__dirname, "../dist"),
assets: "assets"
}
const PAGES_DIR = `${PATHS.src}/views/pages/`
const PAGES = fs.readdirSync(PAGES_DIR).filter(fileName => fileName.endsWith(".pug"))
// Main config
module.exports = {
mode: "production",
devtool: false,
output: {
filename: "js/bundle.min.js",
path: PATHS.dist,
publicPath: "",
clean: true
},
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin(),
new ImageMinimizerPlugin({
generator: [
{
filter: (source, sourcePath) => {
// The `source` argument is a `Buffer` of source file
// The `sourcePath` argument is an absolute path to source
if (source.byteLength < 8192) {
return false;
}
return true;
},
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: ImageMinimizerPlugin.imageminGenerate,
options: {
plugins: ["imagemin-webp"],
},
},
],
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
]
}
},
}),
]},
module: {
rules: [
{
test: /\.pug$/,
loader: "pug-loader",
options: {
pretty: true
}
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../"
}
},
"css-loader",
"postcss-loader",
"sass-loader"
],
},
{
test: /\.(png|jpeg|jpg|gif|svg|webp)$/i,
type: "asset/resource",
generator: {
filename: 'images/[name][ext]'
}
},
{
test: /\.svg$/,
type: "asset",
generator: {
dataUrl(content) {
content = content.toString();
return miniSVGDataURI(content);
}
},
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: "asset/resource",
generator: {
filename: "fonts/[name][ext]"
}
}
]
},
resolve: {
alias: {
"~": PATHS.src,
"~modules": `${PATHS.src}/views/modules`,
}
},
plugins: [
new SVGSpritemapPlugin(`${PATHS.src}/images/sprites/*.svg`,
{
output: {
filename: `/images/sprites.svg`,
svg: {
sizes: true
}
},
sprite: {
prefix: false,
generate: {
title: false,
use: true,
symbol: true,
}
},
styles: {
filename: `${PATHS.src}/styles/base/_sprites.scss`,
variables: {
sprites: "sprite",
sizes: "size"
},
}
}),
new MiniCssExtractPlugin({
filename: "css/[name].min.css"
}),
new CopyWebpackPlugin({
patterns: [
{ from: `${PATHS.src}/static`, to: "" },
{
from: `${PATHS.src}/images`,
to: "images",
globOptions: {
ignore: [
"**/images/*.webp"
]
}
},
]
}),
// Automatic creation any html pages (Don"t forget to RERUN dev server)
...PAGES.map(page => new HtmlWebpackPlugin({
template: `${PAGES_DIR}/${page}`,
filename: `./${page.replace(/\.pug/, ".html")}`,
inject: "body"
})),
new HtmlBeautifyPlugin({
end_with_newline: true,
indent_size: 2,
indent_with_tabs: true,
indent_inner_html: true,
preserve_newlines: true,
unformatted: ["p", "i", "b", "span"]
}),
When i bundle split my webpack vendor ( node_modules ) my main.js file prints out the following message. When i disable bundle splitting, it works. But when I bundle split and i console.log the module (responsiveMenu) It complains about callbacks. I'm using the webpack bundle-loader to create my code splitted bundle.
my dist folder ususlly ends up like the following
main.js
bundle.1.js
bundle.2.js
bundle.x.js etc
below is my webpack file, the top of main.js and responsiveMenu.js, my babelrc.js is also present
babelrc.js
api.cache(true);
const presets = [['#babel/preset-env', {
"targets": {
"esmodules": true
}
}]];
const plugins = ['#babel/plugin-proposal-export-default-from', '#babel/plugin-transform-runtime'];
return {
presets,
plugins,
};
};
Webpack config
const webpack = require('webpack');
const minimatch = require('minimatch');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const TerserPlugin = require('terser-webpack-plugin');
const LiveReloadPlugin = require('webpack-livereload-plugin');
const globImporter = require('node-sass-glob-importer');
const CopyPlugin = require('copy-webpack-plugin');
const HappyPack = require('happypack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const PhpManifestPlugin = require('webpack-php-manifest');
const phpManifest = new PhpManifestPlugin();
const devMode = 'development' === process.env.NODE_ENV;
module.exports = {
resolve: {
alias: {
assets: path.resolve(__dirname, 'assets'),
fonts: path.resolve(__dirname, 'assets/fonts'),
modernizr$: path.resolve(__dirname, './.modernizrrc')
}
},
mode: process.env.NODE_ENV,
entry: {
'js/main': './assets/js/scripts/main.js',
'css/style': './assets/scss/style.scss'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
chunkFilename: 'js/bundle.[id].js',
publicPath: 'wp-content/themes/strafe-boilerplate/dist/'
},
devtool: devMode ? 'source-map' : 'cheap-eval-source-map',
performance: {
maxAssetSize: 1000000
},
optimization: {
minimize: !devMode,
removeAvailableModules: !devMode,
removeEmptyChunks: !devMode,
splitChunks: !devMode ? {
maxInitialRequests: Infinity,
minSize: 0,
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
name: 'vendors',
vendors: {
test: /node_modules/,
name(module, chunks, cacheGroupKey) {
const moduleFileName = module
.identifier()
.split('/')
.reduceRight(item => item);
const allChunksNames = chunks.map(item => item.name).join('');
let name = `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
return name;
}
},
}
} : false,
minimizer: !devMode ? [
new TerserPlugin({
sourceMap: !devMode,
cache: !devMode,
parallel: true
})
] : []
},
stats: {
assets: !devMode,
builtAt: !devMode,
children: false,
chunks: false,
colors: true,
entrypoints: !devMode,
env: false,
errors: !devMode,
errorDetails: false,
hash: false,
maxModules: 20,
modules: false,
performance: !devMode,
publicPath: false,
reasons: false,
source: false,
timings: !devMode,
version: false,
warnings: !devMode
},
module: {
rules: [
!devMode ?
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
include: path.resolve(__dirname, 'assets/js'),
use: ['happypack/loader', {
loader : 'bundle-loader'
}]
} : {
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
include: path.resolve(__dirname, 'assets/js'),
use: ['happypack/loader']
},
{
test: /\.(sa|sc|c)ss$/,
exclude: /(node_modules|bower_components)/,
include: path.resolve(__dirname, 'assets/scss'),
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true,
url: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
{
loader: 'resolve-url-loader',
options: {
engine: 'postcss',
root: path.resolve(__dirname, 'assets')
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
importer: globImporter(),
outputPath: 'css',
debug: true
}
}
]
},
{
test: /\.(png|jpg|gif)$/,
include: path.resolve(__dirname, 'assets/img'),
use: [
{
loader: 'file-loader',
options: {
outputPath: 'img',
name: '[folder]/[name].[ext]',
publicPath: '../img/',
useRelativePath: true
}
}
]
},
{
test: /\.(eot|woff|woff2|ttf)([\?]?.*)$/,
include: path.resolve(__dirname, 'assets/fonts'),
use: [
{
loader: 'file-loader',
options: {
outputPath: 'fonts',
name: '[folder]/[name].[ext]',
debug: true,
publicPath: '../fonts/',
useRelativePath: true
}
}
]
},
{
test: /\.(svg)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'img',
name: '[folder]/[name].[ext]',
publicPath: '../img/',
useRelativePath: true
}
},
{
loader: 'svgo-loader',
options: {
plugins: [
{ removeTitle: false },
{ convertColors: { shorthex: false } },
{ convertPathData: false },
{ removeViewBox: false }
]
}
}
]
},
{
test: /\.modernizrrc.js$/,
use: ['modernizr-loader']
},
{
test: /\.modernizrrc(\.json)?$/,
use: ['modernizr-loader', 'json-loader']
}
]
},
plugins: [
new HappyPack({
loaders: [
{
loader: 'babel-loader',
options: {
presets: [ '#babel/preset-react' ]
}
}
]
}),
new webpack.ProvidePlugin({
'Promise': 'bluebird'
}),
phpManifest,
devMode && new FriendlyErrorsPlugin({
clearConsole: false
}),
new CleanWebpackPlugin(['dist'], {
cleanStaleWebpackAssets: false,
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: !devMode ? 'css/bundle.[id].css' : false
}),
!devMode && new ImageminPlugin({
test: /\.(jpe?g|png|gif)$/i,
cacheFolder: './imgcache'
}),
devMode && new LiveReloadPlugin(),
new CopyPlugin([{ from: 'assets/img', to: 'img' }])
].filter(Boolean)
};
responsiveMenu.js
function responsiveMenu() {
// Responsive Menu
// Setup Doc, call out functions
function init() {
const toggleTrigger = $('.mobile-toggle');
const menuWrap = $('.menu-responsive');
menuPositionSetup(menuWrap);
triggerMenu(toggleTrigger, menuWrap);
childItemsHandler();
}
function menuPositionSetup(menu) {
let headerHeight = $('.header').outerHeight(true);
$(menu).css('top', headerHeight);
$(menu).css({ height: 'calc(100% - ' + headerHeight + 'px)' });
}
function triggerMenu(toggle, menu) {
$(toggle).on('click', function(e) {
mobileToggle($(this), menu);
});
}
function mobileToggle(trigger, menu) {
$(menu).toggleClass('is-active');
$(trigger).toggleClass('is-active');
$('body').toggleClass('is-overflow-h');
}
function childItemsHandler() {
$('.menu-item-has-children > a').on('click', function(e) {
if ($(this).hasClass('is-active')) {
// Go to the link
} else {
// Open the sub menu
$(this).addClass('is-active');
$(this)
.parent()
.find('.sub-menu')
.slideDown();
e.preventDefault();
}
});
}
};
export default responsiveMenu
main.js
import * as $ from 'jquery';
import responsiveMenu from './responsiveMenu';
console.log(responsiveMenu)
$(document).ready(function() {
init();
});
function init() {
responsiveMenu()
}
entry: {
vender: [
'react',
'react-dom',
'eslint-plugin-react',
],
},
The code snippet above seems to be the cause of my issues. This code sample is a part of my webpack.config.js file. If I run yarn build for this application it removes my CSS file that was being created through the ExtractTextWebpackPlugin (ETP in my code). If I comment out the code section above the CSS file is present in the public directory after I run build. Would anyone happen to know how I can remedy this issue.
const ETP = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const merge = require('webpack-merge');
const OpenBrowserPlugin = require('open-browser-webpack-plugin');
const parts = require('./webpack.parts');
const path = require('path');
const webpack = require('webpack');
const glob = require('glob');
const PATHS = {
public: path.join(__dirname, 'public'),
src: path.join(__dirname, 'src'),
styles: path.join(__dirname, 'src', 'scss'),
};
const options = {
host: 'localhost',
port: '8085',
};
const commonConfig = merge([
{
entry: PATHS.src,
output: {
path: PATHS.public,
filename: '[name].bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Jason Ganz Portfolio',
template: path.join(PATHS.src, 'index.html'),
}),
new OpenBrowserPlugin({
url: `http://${options.host}:${options.port}`,
}),
new ETP('style.css'),
new webpack.LoaderOptionsPlugin({
options: {
eslint: {
failOnWarning: false,
failOnError: true,
fix: false,
// // Output to Jenkins compatible XML
// // outputReport: {
// // filePath: 'checkstyle.xml',
// // formatter: require('eslint/lib/formatters/checkstyle'),
// // },
},
},
}),
parts.purifyCSS({
paths: glob.sync(`${PATHS.src}/**/*.js`, {nodir: true}),
}),
],
},
parts.loadSASS(PATHS.styles),
parts.loadJSX(),
]);
const productionConfig = merge([
//Generates Source Maps for js files
parts.generateSourceMaps({ type: 'source-map' }),
{
entry: {
vender: [
'react',
'react-dom',
'eslint-plugin-react',
],
},
plugins: [ new webpack.optimize.CommonsChunkPlugin({name: 'vendor'})],
},
]);
const developmentConfig = merge([
parts.devServer({
host: options.host,
port: options.port,
path: PATHS.public,
}),
{
output: {
devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]',
},
},
parts.generateSourceMaps({ type: 'cheap-module-eval-source-map' }),
]);
module.exports = (env) => {
if(env == 'development') {
return merge(commonConfig, developmentConfig);
}
return merge(commonConfig, productionConfig);
};
My loaders and modules are being stored in a separate webpack.parts.js file which can be seen below.
const ETP = require('extract-text-webpack-plugin');
const PurifyCSSPlugin = require('purifycss-webpack');
exports.devServer = ({host, port, path} = {})=> ({
devServer: {
compress: true,
contentBase: path,
historyApiFallback: true,
host,
port,
overlay: {
errors: true,
warnings: true,
},
stats: 'errors-only',
},
});
exports.generateSourceMaps = ({ type }) => ({
devtool: type,
});
exports.loadCSS = () => ({
module:{
loaders: [{
test: /\.css$/,
loader: ['style-loader','css-loader'],
}],
},
});
exports.loadJSX = () => ({
module:{
loaders: [{
test: /\.(js|jsx)$/,
exclude: '/node_modules/',
loader: 'babel-loader',
}],
},
});
exports.loadSASS = (path) => ({
module: {
loaders: [{
test: /\.(css|sass|scss)$/,
loader: ETP.extract({
fallback: 'style-loader',
use: 'css-loader!postcss-loader!sass-loader',
}),
include: path,
}],
},
});
exports.purifyCSS = ({ paths }) => (new PurifyCSSPlugin({paths}))
You are writing "vender" instead of "vendor" in the entry property