I realise this question is a little out there and not very informative, but the webpack code runs perfectly on linux based systems.
Simply, the script takes an env variable which is a folder name (contains the js to be compiled), then compiles each of the js files inside this given folder. Creates some js from this, then passes that down to compile.js once webpack has finished its business.
package.json
"start_windows": "set BABEL_ENV=development/client&&npm run clean && webpack --watch",
I am most surprised that line 14 of webpack does not run console.info("sdhfjkzhsdkfhzsdjkfh================",env);
webpack.base.config.js
const path = require("path");
const getEntries = require("./scripts/build/getEntries");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const WebpackShellPlugin = require("webpack-shell-plugin");
const envGenerator = require("./scripts/build/handleEnv");
const LiveReloadPlugin = require("webpack-livereload-plugin");
console.info("aaaaaaaaaaaaaaaaaaaaaaa");
/**
* Webpack config
*/
module.exports = function() {
const optionsReload = {};
const env = envGenerator(process.env.npm_config_argv);
console.info("sdhfjkzhsdkfhzsdjkfh================",env);
return {
entry: getEntries(env),
plugins: [
new webpack.LoaderOptionsPlugin({
debug: true
}),
new ExtractTextPlugin("[name]/styles.css"),
new LiveReloadPlugin(optionsReload),
new WebpackShellPlugin({
onBuildEnd: ["node ./scripts/build/compile.js"],
dev: false // Allows script to run more than once (i.e on every watch)
})
],
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "postcss-loader", "sass-loader"]
})
}
]
},
output: {
path: path.join(__dirname, "dist"),
publicPath: "/dist/",
filename: "[name]/script.js"
}
};
};
cygwin
shruti#ASGLH-WL-12111 /cygdrive/c/Source/asos-mvt-framework
$ npm run build -- -env T1106-premier-upsell
> mvt-framework#0.0.2 build C:\Source\asos-mvt-framework
> npm run clean && webpack -p "-env" "T1106-premier-upsell"
npm WARN invalid config loglevel="notice"
> mvt-framework#0.0.2 clean C:\Source\asos-mvt-framework
> rm -rf ./dist/*
3.8.1 //output here where webpack should be running
> mvt-framework#0.0.2 postbuild C:\Source\asos-mvt-framework
> node ./scripts/build/compile.js
C:\Source\asos-mvt-framework\dist []
getEntries.js
const fs = require("fs");
const path = require("path");
// Directory where our Multi Variant Tests reside
const mvtFolderPath = path.resolve("./src/tests");
/**
* Loop through the JS files in the test folder root
* and define a new bundle for each one
*/
module.exports = function(testFolderName) {console.info(testFolderName);
const entries = {};
const testFolderPath = path.resolve(mvtFolderPath, testFolderName);
fs.readdirSync(testFolderPath).forEach(file => {
const fileName = path.parse(file).name;
const fileExt = path.parse(file).ext;
if (fileExt === ".js") {
entries[fileName] = path.resolve(testFolderPath, file);
}
});
return entries;
};
handleEnv.js
module.exports = function(env) {
console.info(env);
const envCooked = JSON.parse(env).cooked;
if (envCooked.length === 1) {
// eslint-disable-next-line no-console
console.error("\x1b[31m%s\x1b[0m", "ERROR: Please supply a test folder");
console.error(
"\x1b[31m%s\x1b[0m",
"For Example: `npm start T9999-somme-test`"
);
console.info(`
No env given
`);
process.exit();
}
return envCooked[3].substr(0, 1) === "T" ? envCooked[3] : envCooked[4];
};
Related
So, I'm trying to get this application setup so I can start coding it. But everytime I build the application; webpack automatically adds auto/file.js to the script tags, but it should really be: file.js. So it's adding the auto/ part by itself. I've checked every webpack config file, and I cannot understand why it adds the auto/ prefix to my scripts.
Also like to mention this is a ElectronJS project.
Here are my configurations for webpack.
webpack.config.js
const mainConfig = require("./webpack.main.config");
const rendererConfig = require("./webpack.renderer.config");
const config = [mainConfig, rendererConfig];
module.exports = config;
webpack.base.config.js
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const config = {
plugins: [
new UglifyJsPlugin({
test: /\.js($|\?)/i,
sourceMap: true,
uglifyOptions: {
compress: true
}
})
]
};
module.exports = config;
webpack.main.config.js
const path = require("path");
const merge = require("webpack-merge");
const base = require("./webpack.base.config");
const buildPath = path.resolve(__dirname, "./dist");
const main = merge(base, {
entry: "./main.js",
output: {
filename: "main.js",
path: buildPath
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: "babel-loader"
},
]
},
node: {
__dirname: false,
__filename: false
},
target: "electron-main"
});
module.exports = main;
webpack.renderer.config.js (this is where i think the problem is happening)
const path = require("path");
const merge = require("webpack-merge");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const base = require("./webpack.base.config");
const buildPath = path.resolve(__dirname, "./dist");
const renderer = merge(base, {
entry: "./src/renderer.js",
output: {
filename: "renderer.js",
path: buildPath
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html"
})
],
target: "electron-renderer",
});
module.exports = renderer;
And after the build, when I open the index.html file from the dist directory, the script tag is like this: <script src="auto/renderer.js"></script> when it should just be <script src="renderer.js"></script>
What could be causing this? Is there any configuration I am missing here?
Thanks in advance!
Solved it by updating webpack.
I have issue using webassembly wasm file in React with Typescript.
I have install react-app-rewired and wasm-loader and my config-overrides.js:
const path = require('path');
module.exports = function override(config, env) {
const wasmExtensionRegExp = /\.wasm$/;
config.resolve.extensions.push('.wasm');
config.module.rules.forEach(rule => {
(rule.oneOf || []).forEach(oneOf => {
if (oneOf.loader && oneOf.loader.indexOf('file-loader') >= 0) {
// make file-loader ignore WASM files
oneOf.exclude.push(wasmExtensionRegExp);
}
});
});
// add a dedicated loader for WASM
config.module.rules.push({
test: wasmExtensionRegExp,
include: path.resolve(__dirname, 'src'),
use: [{ loader: require.resolve('wasm-loader'), options: {} }]
});
return config;
};
in package json I change to use "start": "react-app-rewired start",
but still have the same error.
How can solve this issue?
Thank you!
"magic header not detected" indicates that your .wasm file is not really a .wasm file. Can you verify that it is a valid file using wasm-objdump?
I have divided my configuration in to two production and development mode and merging them using webpack-merge.
Whenever i try to build or run the code it gives me you may need an appropriate loader error even though i have define loader for the jsx or js files.
Common Config File code is here...
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
module.exports = {
entry : "./src/index.js",
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
},
{
test: /.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
}
Production Config Code is
const path = require("path");
const common = require("./webpack.config");
const merge = require("webpack-merge");
module.exports = (common, {
mode : "production",
output: {
filename : "bundle.[contentHash].js",
path : path.resolve(__dirname, "dist")
}
});
Development Config Code
const path = require("path");
const common = require("./webpack.config.js");
const merge = require("webpack-merge");
module.exports = (common, {
mode : "development",
output: {
filename : "bundle.js",
path : path.resolve(__dirname, "dist")
}
});
index.js code
import "./assets/scss/main.scss";
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render() {
return <h1>Hello</h1>
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
.babelrc code
{
"presets": ["env", "react","#babel/preset-env"],
"plugins": [
"transform-class-properties"
]
}
You will need to call merge on both your files, merging common with the object specified for each case:
// webpack.prod.js
const path = require("path");
const common = require("./webpack.config");
const merge = require("webpack-merge");
module.exports = merge(common, {
mode : "production",
output: {
filename : "bundle.[contentHash].js",
path : path.resolve(__dirname, "dist")
}
});
// webpack.dev.js
const path = require("path");
const common = require("./webpack.config.js");
const merge = require("webpack-merge");
module.exports = merge(common, {
mode : "development",
output: {
filename : "bundle.js",
path : path.resolve(__dirname, "dist")
}
});
That error occurs because your JSX is not being compiled to JavaScript.
The test in your config file that handles this is:
test: /.(js|jsx)$/,
loader: 'babel-loader',
I see that you've imported "webpack-merge" but it does not appear that you're using it (at least in the code that is displayed in your question).So it seems like you're not merging the disparate config files in the way you're expecting (or maybe at all).
Instead of splitting your config into multiple files, usually [from what I've seen] developers prefer to use one file with some logic in it based on an environmental variable: https://webpack.js.org/guides/environment-variables/
process.env.NODE_ENV === 'dev' ? doDevStuff : doProdStuff
dockerfile:
ARG MY_VAR
ENV NODE_ENV production
ENV MY_VAR $MY_VAR
COPY . .
RUN NODE_ENV=development npm install && \
touch ./.env && \
eval env > ./.env && \
npm run build && \
npm prune --production
Docker newb here
In my container I run a env command and see the variables I've set, also when running a node console I can see they are set in process.env
But when my project builds, all my env variables are undefined (they are not available during that RUN command)
The eval env > ./.env && line DOES put the vars I set with ENV command into the .env, but I can't have those variables hardcoded in the dockerfile
I wish I could do something like:
ENV MY_VAR $process.env.MY_VAR
Anything like that to grab my environment variables?
edit:
webpack.config.js:
require('dotenv').config()
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const BUILD_PATH = path.resolve(__dirname, "./client/build") + '/';
const SOURCE_PATH = path.resolve(__dirname, "./client/src") + '/';
const PUBLIC_PATH = path.resolve(__dirname, "./client/build") + '/';
const env = require('./env')(PUBLIC_PATH)
module.exports = () => {
return {
entry: ["idempotent-babel-polyfill", SOURCE_PATH + "/index.jsx"],
context: SOURCE_PATH,
output: {
path: BUILD_PATH,
filename: "bundle.js",
publicPath: PUBLIC_PATH
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
{ loader: "babel-loader" },
]
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "sass-loader" }
]
},
{
test: /\.(png|jpg|gif)$/,
exclude: /node_modules/,
use: [
{ loader: "file-loader" }
]
}
]
},
devServer: {
compress: true,
port: 3002,
historyApiFallback: true,
contentBase: BUILD_PATH,
publicPath: PUBLIC_PATH
},
devtool: "eval-source-map",
plugins: [
new webpack.DefinePlugin(env),
new HtmlWebpackPlugin({
filename: "index.html",
template: path.resolve(SOURCE_PATH + "/index.html"),
inject: true
}),
new webpack.optimize.UglifyJsPlugin(),
],
watch: false,
}
};
env.js:
require('dotenv').config()
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
var REACT_APP = /^REACT_APP_/i;
function getClientEnvironment(publicUrl) {
var processEnv = Object
.keys(process.env)
.filter(key => REACT_APP.test(key))
.reduce((env, key) => {
env[key] = process.env[key];
return env;
}, {
'NODE_ENV': process.env.NODE_ENV || 'development',
'MY_VAR': process.env.MY_VAR // for example
});
processEnv['process.env'] = Object
.keys(processEnv)
.reduce((env, key) => {
env[key] = JSON.stringify(processEnv[key]);
return env;
}, {})
return processEnv;
}
module.exports = getClientEnvironment;
Doing a build command inside docker's CMD statement solves this issue
In webpack, CopyWebpackPlugin causes infinite loop when webpack is in watch mode. I tried to add watchOptions.ignored option but it doesn't seem to work.
My webpack config is following:
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const config = {
entry: {
'res': './src/index.js'
},
output: {
filename: '[name].min.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'production',
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new CopyWebpackPlugin([
{ from: 'dist', to: path.resolve(__dirname, 'docs/js') }
], {})
],
watchOptions: {
ignored: path.resolve(__dirname, 'docs/js')
}
};
module.exports = config;
Any help would be appreciated.
With CopyWebpackPlugin, I've experienced the infinite loop too. I tried all kinds of CopyWebpackPlugin configurations with no luck yet. After hours of wasted time I found I could hook into the compiler and fire off my own copy method.
Running Watch
I'm using webpack watch to watch for changes. In the package.json, I use this config so I can run npm run webpackdev, and it will watch for file changes.
"webpackdev": "cross-env webpack --env.environment=development --env.basehref=/ --watch"
My Workaround
I've added an inline plugin with a compiler hook, which taps into AfterEmitPlugin. This allows me to copy after my sources have been generated after the compile. This method works great to copy my npm build output to my maven target webapp folder.
// Inline custom plugin - will copy to the target web app folder
// 1. Run npm install fs-extra
// 2. Add fix the path, so that it copies to the server's build webapp folder
{
apply: (compiler) => {
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
// Debugging
console.log("########-------------->>>>> Finished Ext JS Compile <<<<<------------#######");
let source = __dirname + '/build/';
// TODO Set the path to your webapp build
let destination = __dirname + '/../dash-metrics-server/target/metrics-dash';
let options = {
overwrite: true
};
fs.copy(source, destination, options, err => {
if (err) return console.error(err) {
console.log('Copy build success!');
}
})
});
}
}
The Workaround Source
Here's my webpack.config.js in total for more context. (In this webpack configuration, I'm using Sencha's Ext JS ExtWebComponents as the basis.)
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { BaseHrefWebpackPlugin } = require('base-href-webpack-plugin');
const ExtWebpackPlugin = require('#sencha/ext-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
const fs = require('fs-extra');
module.exports = function(env) {
function get(it, val) {if(env == undefined) {return val;} else if(env[it] == undefined) {return val;} else {return env[it];}}
var profile = get('profile', '');
var emit = get('emit', 'yes');
var environment = get('environment', 'development');
var treeshake = get('treeshake', 'no');
var browser = 'no'; // get('browser', 'no');
var watch = get('watch', 'yes');
var verbose = get('verbose', 'no');
var basehref = get('basehref', '/');
var build_v = get('build_v', '7.0.0.0');
const isProd = environment === 'production';
const outputFolder = 'build';
const plugins = [
new HtmlWebpackPlugin({template: 'index.html', hash: false, inject: 'body'}),
new BaseHrefWebpackPlugin({ baseHref: basehref }),
new ExtWebpackPlugin({
framework: 'web-components',
toolkit: 'modern',
theme: 'theme-material',
emit: emit,
script: './extract-code.js',
port: 8080,
packages: [
'renderercell',
'font-ext',
'ux',
'd3',
'pivot-d3',
'font-awesome',
'exporter',
'pivot',
'calendar',
'charts',
'treegrid',
'froala-editor'
],
profile: profile,
environment: environment,
treeshake: treeshake,
browser: browser,
watch: watch,
verbose: verbose,
inject: 'yes',
intellishake: 'no'
}),
new CopyWebpackPlugin([{
from: '../node_modules/#webcomponents/webcomponentsjs/webcomponents-bundle.js',
to: './webcomponents-bundle.js'
}]),
new CopyWebpackPlugin([{
from: '../node_modules/#webcomponents/webcomponentsjs/webcomponents-bundle.js.map',
to: './webcomponents-bundle.js.map'
}]),
// Debug purposes only, injected via script: npm run-script buildexample -- --env.build_v=<full version here in format maj.min.patch.build>
new webpack.DefinePlugin({
BUILD_VERSION: JSON.stringify(build_v)
}),
// This causes infinite loop, so I can't use this plugin.
// new CopyWebpackPlugin([{
// from: __dirname + '/build/',
// to: __dirname + '/../dash-metrics-server/target/test1'
// }]),
// Inline custom plugin - will copy to the target web app folder
// 1. Run npm install fs-extra
// 2. Add fix the path, so that it copies to the server's build webapp folder
{
apply: (compiler) => {
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
// Debugging
console.log("########-------------->>>>> Finished Ext JS Compile <<<<<------------#######");
let source = __dirname + '/build/';
// TODO Set the path to your webapp build
let destination = __dirname + '/../dash-metrics-server/target/metrics-dash';
let options = {
overwrite: true
};
fs.copy(source, destination, options, err => {
if (err) return console.error(err)
console.log('Copy build success!');
})
});
}
}
];
return {
mode: environment,
devtool: (environment === 'development') ? 'inline-source-map' : false,
context: path.join(__dirname, './src'),
//entry: './index.js',
entry: {
// ewc: './ewc.js',
app: './index.js'
},
output: {
path: path.join(__dirname, outputFolder),
filename: '[name].js'
},
plugins: plugins,
module: {
rules: [
{ test: /\.(js)$/, exclude: /node_modules/,
use: [
'babel-loader',
// 'eslint-loader'
]
},
{ test: /\.(html)$/, use: { loader: 'html-loader' } },
{
test: /\.(css|scss)$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'sass-loader' }
]
}
]
},
performance: { hints: false },
stats: 'none',
optimization: { noEmitOnErrors: true },
node: false
};
};
So I know this question is very old at this point, but I was running into this endless loop issue again recently and found a couple of solutions.
Not the cleanest method, but if you add an "assets" folder, which can be completely empty, to the root of your project, it seems to only compile after your sources folder changes.
The better method I have found is within the webpack config. The original poster mentioned about using ignored which does seem to fix the issue if you instruct webpack to watch file changes after the initial build and to ignore your dist/output folder...
module.exports = {
//...
watch: true,
watchOptions: {
ignored: ['**/dist/**', '**/node_modules'],
},
};