So I am just getting started in learning webpack(2.2.1) and react and I am encountering a bit of a problem with NODE_ENV. I set it in package.json like so:
"scripts": {
"start": "set NODE_ENV=production&& webpack",
"test": "echo \"Error: no test specified\" && exit 1"
}
Then I put a console.log(process.env.NODE_ENV) into the entry file for webpack to see if it set and it does as expected.
However when I go to run express in a file called server.js in the project's root directory:
const express = require('express');
const path = require('path');
const app = new express;
console.log(process.env.NODE_ENV);
const port = process.env.PORT || 3000;
app.use(express.static('public'));
app.get('/',(req,res)=>{
res.sendFile(path.join(__dirname, "public/index.html"));
});
app.listen(port, ()=>{
console.log("listening...", process.env.NODE_ENV);
});
process.env.NODE_ENV is undefined.
Here is the webpack.config
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const VENDOR_LIBS = ['react', 'react-dom', 'bootstrap', 'jquery'];
module.exports = {
entry: {
bundle: './src/index.js',
vendor: VENDOR_LIBS
},
output: {
path: __dirname + '/public',
filename: '[name].js'
},
module: {
rules: [
{
use: 'babel-loader',
test: /\.(js|jsx)$/,
exclude: /node_modules/
},
{
loader: ['style-loader', 'css-loader'],
test: /.css$/
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url?limit=10000&mimetype=application/octet-stream'
},
{
loader: 'url?limit=10000!img?progressive=true',
test: /\.(jpe?g|png|gif|svg)$/i
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
jQuery: 'jquery'
}),
new webpack.optimize.CommonsChunkPlugin({name: "vendor", filename: "vendor.js"}),
new ExtractTextPlugin("./styles/bootstrap.css"),
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)})
]
}
Any help would be greatly appreciated.
Related
I am trying to use React-Native web to convert an existing React Native App to Web App.
The App is getting compiled successfully now, but the page appears blank and I get the following error on checking console.
It is working fine when we don't use the project files and make a simple screen with react native elements like View, Text etc.
rnw_blogpost.bundle.js:31234 Uncaught ReferenceError: exports is not defined
at eval (extends.js:2)
at Module../node_modules/react-redux/node_modules/#babel/runtime/helpers/esm/extends.js (rnw_blogpost.bundle.js:30586)
at __webpack_require__ (rnw_blogpost.bundle.js:31231)
at fn (rnw_blogpost.bundle.js:31457)
at eval (connectAdvanced.js:1)
at Object../node_modules/react-redux/es/components/connectAdvanced.js (rnw_blogpost.bundle.js:17465)
at __webpack_require__ (rnw_blogpost.bundle.js:31231)
at fn (rnw_blogpost.bundle.js:31457)
at eval (index.js:1)
at Object../node_modules/react-redux/es/index.js (rnw_blogpost.bundle.js:17585)
Here is my webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const appDirectory = path.resolve(__dirname);
const {
presets
} = require(`${appDirectory}/babel.config.js`);
const compileNodeModules = [
// Node Modues come here!
].map((moduleName) => path.resolve(appDirectory, `node_modules/${moduleName}`));
const babelLoaderConfiguration = {
test: /\.js$/,
// Add every directory that needs to be compiled by Babel during the build.
include: [
path.resolve(__dirname, 'node_modules/react-native-uncompiled'),
path.resolve(__dirname, 'index.web.js'), // Entry to your application
path.resolve(__dirname, 'App.web.js'), // Change this to your main App file
path.resolve(__dirname, 'src'),
...compileNodeModules,
],
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
// The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
presets: ['module:metro-react-native-babel-preset'],
// Re-write paths to import only the modules needed by the app
plugins: ['react-native-web']
}
}
};
const svgLoaderConfiguration = {
test: /\.svg$/,
use: [{
loader: '#svgr/webpack',
}, ],
};
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
},
},
};
module.exports = {
entry: {
app: path.join(__dirname, 'index.web.js'),
},
output: {
path: path.resolve(appDirectory, 'dist'),
publicPath: '/',
filename: 'rnw_blogpost.bundle.js',
libraryTarget: 'umd'
},
resolve: {
extensions: ['.web.tsx', '.web.ts', '.tsx', '.ts', '.web.js', '.js'],
alias: {
'react-native$': 'react-native-web',
App: path.resolve("src"),
},
},
module: {
rules: [
babelLoaderConfiguration,
imageLoaderConfiguration,
svgLoaderConfiguration,
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.html'),
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
// See: https://github.com/necolas/react-native-web/issues/349
__DEV__: JSON.stringify(true),
}),
],
target: ['node'],
};
& here is the code of my babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
I am building web version from existing React Native project using react-native-web.
webpack.config.js
const path = require('path');
const webpack = require('webpack'); const HtmlWebpackPlugin =
require('html-webpack-plugin');
const appDirectory = path.resolve(__dirname); const {presets} =
require(`${appDirectory}/babel.config.js`);
const compileNodeModules = [ // Add every react-native package that
needs compiling // 'react-native-gesture-handler', ].map(moduleName
=> path.resolve(appDirectory, `node_modules/${moduleName}`));
const babelLoaderConfiguration = { test: /\.js$|(tsx|jsx)?$/, //
Add every directory that needs to be compiled by Babel during the
build. include: [
path.resolve(__dirname, 'index.web.js'), // Entry to your application
path.resolve(__dirname, 'App.web.tsx'), // Change this to your main App file
path.resolve(__dirname, 'src'),
...compileNodeModules, ], use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets,
plugins: ['react-native-web'],
}, }, };
const svgLoaderConfiguration = { test: /\.svg$/, use: [
{
loader: '#svgr/webpack',
}, ], };
const imageLoaderConfiguration = { test: /\.(gif|jpe?g|png)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
}, }, };
module.exports = { entry: {
app: path.join(__dirname, 'index.web.js'), }, output: {
path: path.resolve(appDirectory, 'dist'),
publicPath: '/',
filename: 'fictionate.me.bundle.js', }, resolve: {
extensions: ['.web.tsx', '.web.ts', '.tsx', '.ts', '.web.js', '.js'],
alias: {
'react-native$': 'react-native-web',
}, }, module: {
rules: [
babelLoaderConfiguration,
imageLoaderConfiguration,
svgLoaderConfiguration,
], }, plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.html'),
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
// See: https://github.com/necolas/react-native-web/issues/349
__DEV__: JSON.stringify(true),
}), ], };
babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
When I am trying to build web, it failed with following issue.
enter image description here
Please help me if someone knows how to fix this issue.
I am new to Vuejs Webpack configuration. I am trying to run vuejs app using dev server but unable to. Webpack command is running fine and I am able to build the app successfully and its running fine but when I am trying to run app with dev server its opening up the url on browser itself but throwing console error unable to trace whats going on.
const HtmlWebPackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const { VueLoaderPlugin } = require("vue-loader");
const path = require("path");
module.exports = {
entry: "./index.js",
output: {
path: path.resolve(__dirname, "./dist"),
filename: `js/[name]_[hash]_bundle.js`,
chunkFilename: `js/[name]_[chunkhash]_chunk.js`,
},
devServer: {
port: 4300,
},
module: {
rules: [
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.js$/,
loader: "babel-loader",
},
{
test: /\.(css|scss)$/,
use: ["vue-style-loader", "css-loader", "sass-loader"],
},
],
},
optimization: {
splitChunks: { name: "vendor", chunks: "all" },
},
resolve: {},
plugins: [
new CleanWebpackPlugin(),
new VueLoaderPlugin(),
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html",
}),
],
devtool: "source-map",
};
This is the error I am getting while running webpack-dev-server command,
As you can see here its loading the js bundle files properly here in index.html
I have the following NPM scripts inside package.json:
"scripts": {
"start": "cross-env NODE_ENV=development webpack --mode development",
"build": "cross-env NODE_ENV=production webpack --mode production"
},
if I run npm run build (production mode) I want to add optimization (see below) to compress my CSS and Uglify the Javascript. How do I achieve that?
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
if I run npm start I want to watch the files and further the same as production mode except optimization. I am building a Drupal site so I need to build the assets also in development.
My webpack.config.js looks like this now:
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const config = {
entry: {
main: "./src/index.js",
courses: "./src/courses.js",
vendor: "./src/vendor.js"
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new MiniCssExtractPlugin({ filename: '[name].css' }),
new CopyPlugin([
{ from: './src/assets/images', to: 'assets/images' },
{ from: './src/assets/icons', to: 'assets/icons' }
]),
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader',
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './assets/fonts',
},
},
}
]
}
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
//...
}
if (argv.mode === 'production') {
//...
}
return config;
};
How do I build this in?
I fix it by adjusting webpack.config.js like below:
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const config = {
//Entry Point
entry: {
main: "./src/index.js",
courses: "./src/courses.js",
vendor: "./src/vendor.js"
},
//Output
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
//Watch
watch: false,
watchOptions: {
ignored: ['node_modules']
},
//Loader
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader',
]
},
{
//For fonts
test: /\.(woff|woff2|ttf|otf|eot)$/,
use: [
{
//using file-loader too
loader: "file-loader",
options: {
outputPath: "fonts"
}
}
]
}
]
},
//plugin
plugins: [
new MiniCssExtractPlugin({ filename: '[name].css' }),
new CopyPlugin([
{ from: './src/assets/images', to: 'assets/images' },
{ from: './src/assets/icons', to: 'assets/icons' }
]),
],
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
//...
config.mode = "development";
config.watch = true;
}
if (argv.mode === 'production') {
//...
config.mode = "production";
config.optimization = {
splitChunks: {
chunks: "all"
},
minimize: true,
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin({
cache: true
})
]
};
}
return config;
};
If anybody have improvements on above, please let me know.
I am not sure if this is a webpack issue, vue-loader for webpack issue or just something that I am doing wrong.
When I am running npm run build to build a distribution for my Vue.js application the CSS rules applied in the dist app are in different order then in my development environment thus my CSS overrides are different and app doesn't render right...
Here is demonstration for one element:
npm run dev - proper render
npm run build - improper render
UPDATE: added webpack config files
webpack.base.conf.js
var path = require('path')
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, '../dist/static'),
publicPath: '/static/',
filename: '[name].js'
},
resolve: {
extensions: ['', '.js', '.vue'],
alias: {
'src': path.resolve(__dirname, '../src')
}
},
resolveLoader: {
root: path.join(__dirname, 'node_modules')
},
module: {
preLoaders: [
{
test: /\.vue$/,
loader: 'eslint',
exclude: /node_modules/
},
{
test: /\.js$/,
loader: 'eslint',
exclude: /node_modules/
}
],
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.scss$/,
loaders: ['style', 'css?sourceMap', 'sass?sourceMap']
},
{
test: /\.(png|jp?g|gif|svg|woff2?|eot|ttf)(\?.*)?$/,
loaders: [
'url?limit=20000&name=[name].[ext]?[hash:7]',
'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}'
]
},
{
test: /\.html$/,
loader: 'html'
}
]
},
eslint: {
formatter: require('eslint-friendly-formatter')
},
vue: {
loaders: {
sass: 'style!css!sass?indentedSyntax'
}
},
stylus: {
use: [require('nib')()],
import: ['~nib/lib/nib/index.styl']
}
}
webpack.dev.conf.js
var webpack = require('webpack')
var config = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
// eval-source-map is faster for development
config.devtool = '#eval-source-map'
// add hot-reload related code to entry chunks
var polyfill = 'eventsource-polyfill'
var devClient = './build/dev-client'
Object.keys(config.entry).forEach(function (name, i) {
var extras = i === 0 ? [polyfill, devClient] : [devClient]
config.entry[name] = extras.concat(config.entry[name])
})
// necessary for the html plugin to work properly
// when serving the html from in-memory
config.output.publicPath = '/'
config.plugins = (config.plugins || []).concat([
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
inject: true
})
])
module.exports = config
webpack.prod.conf.js
var webpack = require('webpack')
var config = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
// naming output files with hashes for better caching.
// dist/index.html will be auto-generated with correct URLs.
config.output.filename = '[name].[chunkhash].js'
config.output.chunkFilename = '[id].[chunkhash].js'
// whether to generate source map for production files.
// disabling this can speed up the build.
var SOURCE_MAP = true
config.devtool = SOURCE_MAP ? 'source-map' : false
// generate loader string to be used with extract text plugin
function generateExtractLoaders (loaders) {
return loaders.map(function (loader) {
return loader + '-loader' + (SOURCE_MAP ? '?sourceMap' : '')
}).join('!')
}
// http://vuejs.github.io/vue-loader/configurations/extract-css.html
var cssExtractLoaders = {
css: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css'])),
less: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'less'])),
sass: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'sass'])),
stylus: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'stylus']))
}
config.vue = config.vue || {}
config.vue.loaders = config.vue.loaders || {}
Object.keys(cssExtractLoaders).forEach(function (key) {
config.vue.loaders[key] = cssExtractLoaders[key]
})
config.plugins = (config.plugins || []).concat([
// http://vuejs.github.io/vue-loader/workflow/production.html
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.optimize.OccurenceOrderPlugin(),
// extract css into its own file
new ExtractTextPlugin('[name].[contenthash].css'),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /src/index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: '../index.html',
template: 'src/index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
})
])
module.exports = config
What helped me, was tapping into the html plugin config, by adding this to vue.config.js
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].chunksSortMode = function (chunk1, chunk2) {
const order = ['first', 'second', 'third']
const order1 = order.indexOf(chunk1.names[0])
const order2 = order.indexOf(chunk2.names[0])
return order1 - order2
}
return args
})
},