Webpack sideEffects wont remove unused function - javascript

In the babel-loader iam declaring side-effects to false which means that any unused function should me removed from the bundle. But in my case logFour function remains.
util.js
export function logThree() {
console.log(3);
}
export function logFour() {
console.log(4);
}
logThree();
logFour();
index.js
import { logThree } from "./util";
logThree();
bundle.js
(() => {
"use strict";
function o() {
console.log(3);
}
o(), console.log(4), o();
})();
webpack
module.exports = {
mode: "production",
entry: ["./src/index"],
devtool: "source-map",
output: {
path: path.resolve("dist/"),
publicPath: "/public/assets/",
filename: "main.js",
},
optimization: {
usedExports: true,
},
devServer: {
contentBase: "./src",
},
resolve: {
extensions: [".js"],
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
sideEffects: false,
},
],
},
};

First, there is no such option sideEffects: false inside webpack config. You should put it in package.json.
Second, based on your probably copy-pasted bundle.js, since it's not minimized I suspect you didn't run webpack with this flag --mode production. So no removal.

Related

Why isn't webpack retaining console.log statements?

I'm doing my first tests with webpack and experimenting with code splitting, and I simply wanted to log from my index.js file. It gets compiled, but it doesn't log nothing, both in development or in production mode. Files are compiled and loaded. Very strange. I'm sure I'm doing something wrong... Could you please point me in the right direction?
// index.js
import _ from 'lodash';
import Swiper from 'swiper';
import { Fancybox, Carousel, Panzoom } from "#fancyapps/ui";
function log(){
console.log('from index');
console.log(Swiper);
console.log(Fancybox, Carousel, Panzoom);
console.log(_);
}
log();
webpack config:
const path = require('path');
module.exports = {
//mode: 'development',
mode: 'production',
watch: true,
entry: {
index: './src/index.js',
//page_2: './src/page-2.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
optimization: {
splitChunks: {
cacheGroups: {
visuals: {
name: 'visuals',
chunks: 'all',
test: /[\\/]node_modules[\\/](swiper|#fancyapps\/ui|dom7|ssr-window)[\\/]/
},
lowdash: {
name: 'lowdash',
chunks: 'all',
test: /[\\/]node_modules[\\/]lodash[\\/]/
}
},
}
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: { presets: ['#babel/preset-env'] }
}
} // babel
] // rules
} // module
};
My guess would the as part of the optimization that webpack does, it cleans out your console.logs.
You could try adding
optimization: {
minimize: false,
},
};
and see if that helps. Although I'm surprised it's doing it in dev mode as well.

VM2 Usage with Webpack

I've been having trouble using webpack with a typescript project that uses vm2.webpack --config webpack.config.js gives the following error:
ERROR in index.js from Terser
Invalid function parameter [webpack://./node_modules/source-map-loader/dist/cjs.js!./node_modules/vm2/lib/main.js:1226,1][index.js:1262,21]
This is the minimal repro I've been testing with:
import { VM } from 'vm2';
export async function run(): Promise<void> {
new VM();
}
By using the optimization: { minimize: false } } option in my webpack.config.js I was able to find the source of the error. In the vm2 package source code this block exists:
const HOST = {
...,
require,
...
}
which gets webpacked as:
const HOST = {
...,
__webpack_require__(952),
...
}
This clearly fails. I'm not sure what I else I can do here, is there a config somewhere I can change to
My webpack.config.js:
const path = require('path');
module.exports = {
target: 'node',
entry: './vm2index.ts',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs',
},
// optimization: {
// minimize: false,
// },
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
devtool: 'source-map',
mode: 'production',
// Add the loader for .ts files.
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader',
exclude: /node_modules/,
},
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
},
],
},
stats: {
warningsFilter: [
"Module not found: Error: Can't resolve 'encoding'",
"Cannot find SourceMap 'typescript.js.map'",
],
}
};

Import SCSS as string

I'm trying to import some SCSS into a Javascript file with mixed results. I've found that this works:
style.styleString.scss
body {
background: #556;
}
.test {
&__child {
color: red;
}
}
index.js
import "./index.style"; // making sure that nothing we do breaks normal SCSS importing
const css = require("!!raw-loader!sass-loader!./style.stringStyle.scss").default;
console.log(css);
index.style.scss is correctly compiled to a file and style.stringStyle.scss is correctly printed in the console.
What I'd like to do is move this loader pipeline into my webpack config. This is what I have at the moment:
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import path from "path";
const config = {
mode: "development",
entry: {
"app": "./src/index.js",
},
output: {
path: path.resolve(process.cwd(), "dist"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.stringStyle.scss$/i,
use: [
"raw-loader",
"sass-loader",
],
},
{
test: /\.scss$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader:"css-loader",
options: {
url: false,
},
},
"sass-loader",
],
},
],
},
resolve: {
extensions: [".js", ".scss", ".css"],
},
devtool: "source-map",
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
};
export default config;
index.js
import "./index.style"; // making sure that nothing we do breaks normal SCSS importing
const css = require("./style.stringStyle.scss").default;
console.log(css);
With this configuration, an empty string is printed to the console (index.style.scss still correctly renders to a file).
What am I doing wrong here? I was sort of under the impression that using the inline ! syntax in imports works just like lining up loaders in the config file, but I'm clearly missing something.
Is it possible to setup loading SCSS files as CSS strings in my Webpack config?
Both SCSS tracking rules are getting applied to style.stringStyle.scss. Adding a negative look-behind to the normal import rule's test regex will make sure only the correct rule is selected:
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import path from "path";
const config = {
mode: "development",
entry: {
"app": "./src/index.js",
},
output: {
path: path.resolve(process.cwd(), "dist"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.stringStyle.scss$/i,
use: [
"raw-loader",
"sass-loader",
],
},
{
test: /(?<!\.stringStyle)\.scss$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader:"css-loader",
options: {
url: false,
},
},
"sass-loader",
],
},
],
},
resolve: {
extensions: [".js", ".scss", ".css"],
},
devtool: "source-map",
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
};
export default config;

When typing command "npm run dev" for webpack, it creates a folder that ends with NaN

i'm taking a course in Lynda.com "learning-full-stack-javascript-development-mongodb-node-and-react" and when i use the command "npm run dev" to create a bundle.js file in "public" folder, it creates a folder "publicNaN" and puts the file bundle.js in it.
i want it to be in the "public" folder.
here is the webpack.config.js file:
const path = require("path");
const BUILD_PATH = path.join(__dirname, "./public");
// See https://github.com/Microsoft/vscode/blob/master/extensions/shared.webpack.config.js
module.exports = {
mode: "production",
target: "node",
node: {
__dirname: false
},
entry: {
extension: ["./src/index.js"]
},
output: {
path: BUILD_PATH + + '/public',
filename: "bundle.js",
libraryTarget: "commonjs",
},
resolve: {
extensions: [".ts", ".js"]
},
externals: {
"vscode": "commonjs vscode"
},
module: {
rules: [
{
test: /\.ts$/,
use: [
{
loader: "ts-loader"
}
],
exclude: /node_modules/
},
{
test: /\.mjs$/,
type: "javascript/auto",
use: []
}
]
},
stats: {
children: false,
modules: false
}
};
You're already setting your BUILD_PATH to /public here:
const BUILD_PATH = path.join(__dirname, "./public");
So there's no need to add it in the output object. Also the two + signs tries to convert to a number. That's why you get NaN at the end.
So change the output object to this:
output: {
path: BUILD_PATH,
filename: "bundle.js",
libraryTarget: "commonjs",
},

Webpack Dev Server Not Hot Reloading .vue files

Been working on a project and was sure HMR was working, any of my .js files if I would update them webpack would compile and the module would be replaced all hot like.
I was working on a .vue file and webpack would recompile, but there was no super fresh HMR.
Hoping someone can take a look and tell me if something is off:
The script I'm using in the cli looks like this.
webpack-dev-server --d --watch --output-path ./public --config ./_src/webpack.config.js --progress --env.dev
I'm guessing the most important bit to look at is this:
devServer: {
contentBase: 'public',
hot: true,
filename: 'main.js',
overlay: true,
stats: { colors: true },
port: 3000,
proxy: {
'/': {
target: 'http://moment.local/',
secure: false,
changeOrigin: true
}
},
historyApiFallback: true
},
But here is my whole config if it helps.
const webpack = require('webpack')
const {resolve} = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = env => {
const addPlugin = (add, plugin) => add ? plugin : undefined
const ifProd = plugin => addPlugin(env.prod, plugin)
const removeEmpty = array => array.filter(i => !!i)
// Our Sass Extraction Plugin
const extractSass = new ExtractTextPlugin({
filename: 'style.css',
disable: env.dev
})
return {
entry: {
'vendor': ['jquery', 'KlaviyoSubscribe', 'learnq', 'select2', 'slick-carousel', 'moment', 'lodash'],
'main': resolve(__dirname, './js/index.js')
},
output: {
filename: '[name].js',
path: resolve(__dirname, '../public/'),
pathinfo: !env.prod
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: 'vue-style-loader!css-loader!postcss-loader!sass-loader', // <style lang='scss'>
scss: 'vue-style-loader!css-loader!postcss-loader!sass-loader', // <style lang='scss'>
sass: 'vue-style-loader!css-loader!postcss-loader!sass-loader?indentedSyntax' // <style lang='sass'>
}
}
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{ test: /\.s(c|a)ss$/,
use: extractSass.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
sourceMap: true
}
},
'postcss-loader?sourceMap',
'sass-loader?sourceMap'
]
})
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
devtool: env.prod ? 'source-map' : 'eval',
devServer: {
contentBase: 'public',
hot: true,
filename: 'main.js',
overlay: true,
stats: { colors: true },
port: 3000,
proxy: {
'/': {
target: 'http://moment.local/',
secure: false,
changeOrigin: true
}
},
historyApiFallback: true
},
bail: env.prod, // Fail out on the first error if production
resolve: {
alias: {
'vue$': 'vue/dist/vue.common.js'
}
},
plugins: removeEmpty([
extractSass,
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
// Let's create js for our vendor scripts
name: 'vendor',
// (with more entries, this ensures that no other module
// goes into the vendor chunk)
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: 'commons.js',
// (Modules must be shared between 2 entries)
minChunks: 2
})
...
])
}
}
Really struggling here so anything would be great.
It sounds like you want the "hot" behaviour but you are missing the --hot option in the script you posted. The documentation for that option is here.
You have a lot of options already; just add --hot and that should do the trick.
UPDATE:
I do see that you have the hot: true set in the devServer property of your webpack config, but if I don't use --hot in the cli, I get the following error in the console, so that is why I am saying to use it even though you would think it would be covered by the config - its not.
Uncaught Error: [HMR] Hot Module Replacement is disabled.
Add a file called vue.config.js in your root directory.
Inside it you can enable hot reloading via:
module.exports = {
devServer: {
watchOptions: {
poll: true
}
}
};
I used this settings in a project that was set up via vue create.

Categories

Resources