webpack.config.js
const path = require('path')
HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'index_bundle.js',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ["#babel/preset-env", "#babel/preset-react"],
plugins: ["#babel/plugin-proposal-class-properties"]
}
}
},
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
},
plugins: [
new webpack.DefinePlugin({
APIHOST: JSON.stringify('test'),
BLOCKCHAINHOST: JSON.stringify('test')
}),
new HtmlWebpackPlugin({
template: './src/template.html'
}),
]
}
I defined 2 variables APIHOST and BLOCKCHAINHOST and I tried to console log this in reactjs App.js like so
componentDidMount() {
console.log(APIHOST)
}
The error I'm getting is APIHOST is undefined. I'm not sure what to do here, I've tried adding single quotes for webpack.defineplugin so it looks like 'APIHOST': JSON.stringify('test') but it's still giving me the same error.
You can do like this
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development')
}
})
],
Then in your code
process.env.NODE_ENV
The version I'm using is
"webpack": "^4.29.6"
It looks like this is a known issue:
https://github.com/webpack/webpack/issues/1977
DefinePlugin doesn't work inside React Components
Fixed later on in Webpack 3:
This is fixed. Since webpack 3, the parser now fully understands ES6 semantics.
What version are you using? Does it make sense to upgrade?
Related
Hi there i am trying to use the define plugin so i can update the version number to make sure my JS refreshes after releasing a new build. I can't seem to get DefinePlugin to work properly though. I see it in the folder webpack and i'm trying to follow the documentation but i get errors that it isn't found. Here is my config:
const path = require('path'),
settings = require('./settings');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
'scrollerbundled': [settings.themeLocation + "js/scroller.js"],
'mapbundled': [settings.themeLocation + "js/shopmap.js"],
'sculptor': [settings.themeLocation + "js/sculptor.js"]
},
output: {
path: path.resolve(__dirname, settings.themeLocation + "js-dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
],
plugins: [new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
VERSION: JSON.stringify('5fa3b9'),
})]
},
optimization: {
minimizer: [new UglifyJsPlugin({
uglifyOptions: {
mangle: true,
output: {
comments: false
}
}
})]
},
mode: 'production'
}
{
"parser": "babel-eslint",
"extends": [
"airbnb",
"plugin:react/recommended",
"prettier",
"prettier/react"
],
"plugins": ["react", "import", "prettier"],
"env": {
"browser": true
},
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.dev.js"
}
}
}
}
That's my eslintrc. This is for use absolute imports created in your webpack config with the modules alias. You need to install eslint-import-resolver-webpack
I Have "webpack": "^4.28.4" and define in webpack config
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
});
if you console that variables, you don't find it. I use in conditional
if (PRODUCTION) {
//do stuff
}
Another case is to set globals variables in a object and share with webpack.
here is an example
new webpack.ProvidePlugin({
CONFIG: path.resolve(__dirname, './CONSTS.js')
}),
// the path is src/CONST.JS
In the eslintrc file you can add that variables to avoid import errors.
"settings": {
"import/resolver": {
"webpack": {
"config": "webpack.dev.js"
}
}
}
then in any file you can use import {value} from 'CONFIG'
If you are using laravel mix, you can place that new webpack.DefinePlugin code into the plugins array of your .webpackConfig block:
webpack.mix.js:
mix
.webpackConfig({
devtool: 'source-map',
resolve: {
alias: {
'sass': path.resolve('resources/sass'),
}
},
plugins: [
new webpack.ProvidePlugin({
'window.Quill': 'quill', // <--------------------- this right here
__VERSION__: JSON.stringify('12345')
})
]
})
.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.copy([
'resources/fonts/*',
], 'public/fonts');
By extrapolation, that means you can also add this code to the similar block in your regular (not laravel mix) webpack config.
Install devtools globally
npm install -g #vue/devtools
... and try again.
If уоu have any issues try following the official instructions.
I've been googling for a couple hours now and can't seem to resolve my issue.
I have a webpack/React/Typescript/Mobx setup and am attempting to use firebase.
Here is my webpack config: (boilerplate from this repo)
var webpack = require('webpack');
var path = require('path');
// variables
var isProduction = process.argv.indexOf('-p') >= 0;
var sourcePath = path.join(__dirname, './src');
var outPath = path.join(__dirname, './dist');
// plugins
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
module.exports = {
context: sourcePath,
entry: {
main: './main.tsx'
},
output: {
path: outPath,
filename: 'bundle.js',
chunkFilename: '[chunkhash].js',
publicPath: '/'
},
target: 'web',
resolve: {
extensions: ['.js', '.ts', '.tsx'],
// Fix webpack's default behavior to not load packages with jsnext:main module
// (jsnext:main directs not usually distributable es6 format, but es6 sources)
mainFields: ['module', 'browser', 'main'],
alias: {
app: path.resolve(__dirname, 'src/app/'),
assets: path.resolve(__dirname, 'src/assets/')
}
},
module: {
rules: [
// .ts, .tsx
{
test: /\.tsx?$/,
use: [
isProduction
? 'ts-loader'
: {
loader: 'babel-loader',
options: {
babelrc: false,
plugins: ['react-hot-loader/babel']
}
},
'ts-loader'
],
// : ['babel-loader?plugins=react-hot-loader/babel&presets=', 'ts-loader'],
exclude: /node_modules/
},
// css
{
test: /\.css$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
query: {
modules: true,
sourceMap: !isProduction,
importLoaders: 1,
localIdentName: '[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import')({ addDependencyTo: webpack }),
require('postcss-url')(),
require('postcss-cssnext')(),
require('postcss-reporter')(),
require('postcss-browser-reporter')({
disabled: isProduction
})
]
}
}
]
})
},
{
test: /\.css$/,
include: /node_modules/,
use: ['style-loader', 'css-loader']
},
// static assets
{ test: /\.html$/, use: 'html-loader' },
{ test: /\.(png|jpg)$/, use: 'url-loader?limit=10000' },
{ test: /\.webm$/, use: 'file-loader' }
]
},
optimization: {
splitChunks: {
name: true,
cacheGroups: {
commons: {
chunks: 'initial',
minChunks: 2
},
vendors: {
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: -10
}
}
},
runtimeChunk: true
},
plugins: [
new WebpackCleanupPlugin(),
new ExtractTextPlugin({
filename: 'styles.css',
disable: !isProduction
}),
new HtmlWebpackPlugin({
template: 'assets/index.html'
})
],
devServer: {
contentBase: sourcePath,
hot: true,
inline: true,
historyApiFallback: {
disableDotRule: true
},
stats: 'minimal'
},
devtool: 'cheap-module-eval-source-map',
node: {
// workaround for webpack-dev-server issue
// https://github.com/webpack/webpack-dev-server/issues/60#issuecomment-103411179
fs: 'empty',
net: 'empty'
}
};
Just by including firebase in my app i relentlessly end up with this error:
Uncaught TypeError: Cannot read property 'navigator' of undefined auth.esm.js?69b5:10
I have tested by including a simple component like so:
import * as React from 'react';
import * as Styles from './styles.css';
import 'app/utils/FirebaseUtil';
interface TestProps {}
export const Test: React.StatelessComponent<TestProps > = () => (
<div className={Styles.root}>
{'Hello World'}
</div>
);
FirebaseUtil:
import * as firebase from 'firebase';
const config = {
apiKey: '**my key here**',
authDomain: '** my domain here **'
};
firebase.initializeApp(config);
export const fbAuth = firebase.auth;
No matter what I seem to do I get the navigator error. Even if i dont export the auth object. As far as I can tell its related to babel-loader adding strict-mode according to this SO question, i think? All other related searches seem to have to do with firebase-ui, which i am not using in any way.
But I have no idea how he manages to turn off strict mode, not to mention the OP is not using typescript and I am using ts-loader in this case. I can't for the life of me figure out how to get it working. Aside from all of this if I do try use the firebase object for auth() for example I get a bunch of warnings from webpack about auth not existing on the firebase object. Totally stumped.
So in case anyone else runs into this problem. It appears it was a package version issue. Im assuming that the package versions specifically included in the boilerplate i used didn't play well with firebase.
I updated typescript, react-hot-loader, and most likely the issue webpack from version 3.0.4 to 4.12.1 and things seem to be working ok now. Also with the updates I now import firebase like so:
import firebase from '#firebase/app';
import '#firebase/auth';
Hope this helps someone.
In my case I fixed this importing functions
import firebase from 'firebase/app'
import 'firebase/functions'
import 'firebase/analytics'
I have issue with Webpack building production bundle with test files + test libs included.
In this case it is Enzyme and Jest which we use.
Webpack version 3.10.0
Webpack.build.js
const path = require('path');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = function() {
return {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, '../build'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: [
/node_modules/,
/__snapshots__/,
/test-util/,
],
loader: 'babel-loader'
},
{
test: /\.scss$/,
use: [
{
loader: 'isomorphic-style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
]
},
plugins: [
new UglifyJsPlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}
}),
]
}
};
Here is the file structure
I have tried to workaround the issue by placing Enzyme as external resource in webpack.
externals: {
'enzyme': 'enzyme',
'enzyme-adapter-react-16': 'enzyme-adapter-react-16',
}
That does exclude it from build but (it is workaround) it still builds the snapshot files
I have tried to make "test" regex of babel-loader more specific and exclude test files but it failed.
This is new project and I spent whole day trying to make it bundle only what is necesary. Drained all of my know-how, my google know-how and know-how of the poeple I know or I work with. Hope that SO will be smarter :)
Version
2.5.13
Link to the source code
https://jsfiddle.net/esrgxLfu/
Description
I have a PHP application which uses Vue JS mainly for the settings page. All of settings is created with Vue and we use Webpack. Everything works fine and when we are in the live version there is no console error about Vue being in development mode. We use Vue also for only one component on the dashboard page. It is a Vue TODO list like the one in the Vue documentation. On the dashboard page, we get the console message that Vue is in development mode. We use same Webpack for dashboard and settings page hence the same settings.
I have looked for hours to try to find an answer but I have not been successful which is why I am creating this issue.
In the php file we have this to place the vue component in:
<div id="vue-tasks"></div>
and then we included the javascript file plus the variables.
You can see everything that's being used in the fiddle but I really don't think I can make this reproducible, I'm sorry if you cannot help me with this but it is using a bunch of stuff from PHP Symfony and twig so I was not sure what I could do.
What is expected?
Vue to be in production mode.
What is actually happening?
Vue is in dev environment.
Webpack configuration
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
dashboard: [
'./assets/js/pages/dashboard.js' // Dashboard is the part where we have this issue and the JS is in the fiddle I provided above.
],
settings: [
'./assets/js/pages/settings/main.js'
]
},
output: {
filename: process.env.NODE_ENV === 'production' ? 'js/[name].[chunkhash].js' : 'js/[name].js',
path: path.resolve(__dirname, 'web/dist'),
publicPath: '/dist/'
},
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
]
},
{
test: /\.js$/,
include: path.resolve(__dirname, "assets"),
use: ['babel-loader']
},
{
test: /\.(woff2?|ttf|eot|svg)$/,
loader: 'url-loader?limit=10000&name=fonts/[name].[ext]'
},
{
test: /\.scss$/,
include: path.resolve(__dirname, "assets"),
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader','resolve-url-loader','sass-loader?sourceMap']
})
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader','resolve-url-loader']
})
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
}
},
]
},
resolve: {
alias: {
jquery: "jquery/src/jquery",
'vue$': 'vue/dist/vue.esm.js'
}
},
plugins: [
new ExtractTextPlugin({
filename: process.env.NODE_ENV === 'production' ? 'css/[name].[chunkhash].css' : 'css/[name].css'
}),
new webpack.ProvidePlugin({
'$': 'jquery',
'jQuery': 'jquery'
}),
new WebpackMd5Hash(),
new ManifestPlugin({
basePath: '/dist/'
})
],
performance: {
hints: false
},
devtool: 'source-map'
};
if (process.env.NODE_ENV === 'production') {
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
comments: false,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new CleanWebpackPlugin('dist' , {
root: path.resolve(__dirname, "web"),
verbose: true,
dry: false
})
])
}
Also this is the message I get in console.
You are running Vue in development mode. Make sure to turn on
production mode when deploying for production. See more tips at
https://vuejs.org/guide/deployment.html
It looks like you are picking Vue up using a browser script tag rather than as part of a bundle from your build system.
Altering this to link to a production version of Vue will resolve the issue. In your jsfiddle, for example, replace the script link with https://unpkg.com/vue/dist/vue.min.js.
I have the following in a file initialize.js:
import App from './components/App';
import './styles/application.less';
document.addEventListener('DOMContentLoaded', () => {
const app = new App();
app.start();
});
In webpack.config.js I have:
'use strict';
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const ProvidePlugin = webpack.ProvidePlugin;
const ModuleConcatenationPlugin = webpack.optimize.ModuleConcatenationPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const extractLess = new ExtractTextPlugin({
filename: 'app.css',
});
const webpackCommon = {
entry: {
app: ['./app/initialize']
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader?presets[]=es2015'
}]
}, {
test: /\.hbs$/,
use: {
loader: 'handlebars-loader'
}
}, {
test: /\.less$/,
exclude: /node_modules/,
use: extractLess.extract({
use: [{
loader: 'css-loader'
}, {
loader: 'less-loader'
}],
// use style-loader in development
fallback: 'style-loader'
}),
}]
},
output: {
filename: 'app.js',
path: path.join(__dirname, './public'),
publicPath: '/'
},
plugins: [
extractLess,
new CopyWebpackPlugin([{
from: './app/assets/index.html',
to: './index.html'
}]),
new ProvidePlugin({
$: 'jquery',
_: 'underscore'
}),
new ModuleConcatenationPlugin(),
],
};
module.exports = merge(webpackCommon, {
devtool: '#inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
compress: true,
port: 9000
}
});
I tried removing the the plugins and the contents of application.less, but I keep getting this error:
ERROR in ./node_modules/css-loader!./node_modules/less-loader/dist/cjs.js!./app/styles/application.less
Module build failed: TypeError: Super expression must either be null or a function, not undefined
at ...
# ./app/styles/application.less 4:14-127
# ./app/initialize.js
If I replace that LESS file with a CSS one and update the config it works fine, so I guess the problem has to do with less-loader.
I'm using Webpack 3.4.1, Style Loader 0.18.2, LESS Loader 4.0.5, Extract Text Webpack Plugin 3.0.0 and CSS Loader css-loader.
My bad, I didn't notice I was using an old less version. That was the culprit. Just updated it to 2.7.2 and the problem is gone.