Webpack exclude 3rd party libraries installed via npm - javascript

As for fun I am developing my own html/css admin panel theme migrating from old codebase into webpack as an attempt to make it more modular. Also I use it as an excuse for learning webpack and making my frontend code more test friendly.
My webpack config is:
const path = require('path');
module.exports = {
entry: [
__dirname+"/assets/js/panel.js",
],
output: {
path: __dirname+'/www',
publicPath: '/',
filename: 'panel.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
{
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.scss$/,
use: [
{
loader:'style-loader',
},
// Translates CSS into CommonJS
{
loader:'css-loader'
},
// Compiles Sass to CSS
{
loader:'sass-loader'
},
],
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
],
},
devServer: {
contentBase: path.join(__dirname, 'www'),
compress: true,
port: 8000
}
};
And my assets/js/panel.js is considted of the following code:
// 3rd party libs
import $ from 'jquery';
import bsBreakpoints from 'bs-breakpoints'
import 'bootstrap';
import _ from 'lodash';
import '#fortawesome/fontawesome-free/js/fontawesome'
import '#fortawesome/fontawesome-free/js/solid' // https://fontawesome.com/icons?d=gallery&s=solid&m=free
import '#fortawesome/fontawesome-free/js/regular' // https://fontawesome.com/icons?d=gallery&s=regular&m=free
import '#fortawesome/fontawesome-free/js/brands' // https://fontawesome.com/icons?d=gallery&s=brands&m=free
// Rest of the code is here
Also my package.json is consisted by this settings:
{
"name": "ellakcy_admin",
"version": "1.0.0",
"description": "Admin HTML/CSS template using Bootstrap",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"start": "webpack-dev-server --compress"
},
"keywords": [
"html",
"css",
"admin"
],
"author": "Cypriot FOSS Community",
"license": "GPL",
"dependencies": {
"#fortawesome/fontawesome-free": "^5.4.1",
"bootstrap": "^4.3.1",
"bs-breakpoints": "^1.0.0",
"jquery": "^3.4.1",
"jquery-ui-dist": "^1.12.1",
"popper.js": "^1.16.0",
"saas": "^1.0.0",
"script-loader": "^0.7.2",
"lodash": ">=4.17.13",
"lodash.template": ">=4.5.0"
},
"devDependencies": {
"#babel/core": "^7.7.2",
"#babel/preset-env": "^7.7.1",
"autoprefixer": "^9.7.1",
"babel-loader": "^8.0.6",
"css-loader": "^3.2.0",
"file-loader": "^4.2.0",
"node-sass": "^4.13.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0",
"clean-css": ">=4.1.11"
}
}
So, many themes are being shipped without its 3rd party dependencies so when I build with the js and css with webpack how I can exclude them? I mean it is pointless to ship eg. fontawesome or bootstrap.

Related

ReferenceError: require is not defined #react

I made my own react component npm package and published in npm, now when import and use it in other CRA apps, i get this error when npm start in run in command line .
and in console:
My webpack.config.js file:
var webpack = require('webpack');
var path = require('path');
var nodeExternals = require('webpack-node-externals');
module.exports = {
target: 'web',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
exclude: /(node_modules|bower_components|build)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|woff|woff2|eot|ttf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url?limit=512&&name=[path][name].[ext]?[hash]'
}
]
},
mode: 'development',
externals: {
'react': 'commonjs react'
}
};
My package.json file:
{
"name": "primetable1",
"version": "1.0.0",
"description": "A Datatable for react apps based on Primereact",
"main": "build/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --watch",
"build": "webpack"
},
"keywords": [
"primereact",
"primeicons"
],
"author": "Anish Arya",
"license": "ISC",
"peerDependencies": {
"react": "^16.4.0",
"react-dom": "^16.4.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-env": "^1.7.0",
"babel-runtime": "^6.26.0",
"css-loader": "^3.4.2",
"file-loader": "^5.0.2",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-hot-loader": "^4.12.19",
"react-scripts": "3.4.0",
"style-loader": "^1.1.3",
"webpack-cli": "^3.3.11",
"webpack-node-externals": "^1.7.2"
},
"dependencies": {
"classnames": "^2.2.6",
"primeicons": "^2.0.0",
"primereact": "^3.4.0",
"react-transition-group": "^4.3.0"
}
}
My .babelrc file:
{
"presets": ["env"],
"plugins": [
"transform-object-rest-spread",
"transform-react-jsx",
"react-hot-loader/babel"
]
}
I followed this article to create and publish npm package:
https://codeburst.io/extracting-a-react-js-component-and-publishing-it-on-npm-2a49096757f5
How to solve this error?
The externals configuration seems wrong – you probably only need externals: [nodeExternals()] (from const nodeExternals = require("webpack-node-externals");).

Webpack - MiniCssExtractPlugin doesn't extract file

I've created webpack config to my VueJS project. I want to separate styles from javascript code. I've used mini-css-extract-plugin but finally I receive only bundle.js file. What's wrong with this config and where is a mistake? Is there any missing loader. My config is below:
import path from 'path';
import OptimizeCssAssetsPlugin from 'optimize-css-assets-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import VueLoaderPlugin from 'vue-loader/lib/plugin';
import UglifyJsPlugin from 'uglifyjs-webpack-plugin';
import CleanWebpackPlugin from 'clean-webpack-plugin';
const devMode = process.env.NODE_ENV !== 'production';
const prodPlugins = [
new UglifyJsPlugin(),
new MiniCssExtractPlugin({
filename: "css/style.css"
}),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.optimize\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: true
})
];
const basicPlugins = [
new CleanWebpackPlugin('dist'),
new VueLoaderPlugin()
];
const config = {
entry: {
bundle: './src/main.js'
},
output: {
filename: 'js/[name].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },
{
test: /\.css$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader'
]
},
{ test: /\.(scss|sass)$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'vue-style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
js: 'babel-loader',
}
}
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
plugins: !process.env.NODE_ENV || !devMode ? basicPlugins : basicPlugins.concat(prodPlugins)
};
module.exports = config;
My file package.json
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"watch": "webpack --watch --mode development --hot",
"dev": "webpack-dev-server --mode development --progress --hot --open",
"build": "webpack --mode production --progress"
},
"author": "",
"license": "MIT",
"devDependencies": {
"autoprefixer-loader": "^3.2.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.7.0",
"babel-register": "^6.26.0",
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^0.28.11",
"cssnano": "^3.10.0",
"eslint": "^4.19.1",
"eslint-watch": "^3.1.4",
"mini-css-extract-plugin": "^0.4.0",
"node-sass": "^4.9.0",
"optimize-css-assets-webpack-plugin": "^4.0.1",
"sass-loader": "^7.0.1",
"sass-resources-loader": "^1.3.3",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"vue-loader": "^15.0.10",
"vue-style-loader": "^4.1.0",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"axios": "^0.18.0",
"material-design-icons": "^3.0.1",
"vue": "^2.5.16",
"vue-router": "^3.0.1",
"vuetify": "^1.0.17"
}
}
Note that any imported file is subject to tree shaking. This means if you use something like css-loader in your project and import a CSS file, it needs to be added to the side effect list so it will not be unintentionally dropped in production mode.
Blockquote
in your package.json, add:
"sideEffects": [
'.scss'
]
In Webpack 4, you can add "sideEffects: true" to the loader to prevent the compiler from dropping the CSS file output by MiniCssExtractPlugin.loader (See Webpack Tree Shaking Guide). This works with Angular + TypeScript (using "module:" "ES2015" in tsconfig). I imagine it would work for your set up as well.
{
test: /\.scss$/,
include: [
helpers.root('src', 'assets')
],
sideEffects: true,
use: [
MiniCssExtractPlugin.loader,
{loader: 'css-loader'},
{loader: 'resolve-url-loader'}, // Angular only
{loader: 'sass-loader'},
]
},
Check that you have set the NODE_ENV environment variable.
In your config the extracting of css to separate files (MiniCssExtractPlugin) will only occur when building for production, in other words, when NODE_ENV is set to 'production'. When building for development style-loader is being used which will inject the css within a tag.

Error importing empty class, error TS2307: Cannot find module 'menu'

I'm just trying to do import a simple, blank exported class. Im not sure why it can't find the file because it's in the same directory as the class importing it. I've searched google for similar error codes but no solutions have worked for me and its a relatively simple problem so im quite confused.
Error:
error TS2307: Cannot find module 'menu'
Folder structure:
node_modules/
src/
entry.tsx
menu.tsx
index.html
package-lock.json
package.json
tsconfig.json
webpack.config.js
entry.tsx
import menu from 'menu';
menu.tsx
export default class menu { }
webpack.config
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/entry.tsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [ 'css-loader' ]
})
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}
]
},
plugins: [
new ExtractTextPlugin({
filename: "bundle.css"
}),
new HtmlWebpackPlugin({
title: 'Custom template',
template: 'index.html'
})
]
};
package.json
{
"name": "helloworld",
"version": "1.0.0",
"description": "Hello there",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack-dev-server",
"build:prod": "webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.1",
"html-webpack-plugin": "^2.30.1",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"style-loader": "^0.19.0",
"ts-loader": "^2.3.7",
"typescript": "^2.5.3",
"webpack": "^3.7.1",
"webpack-dev-server": "^2.9.1"
},
"dependencies": {
"#types/react": "^16.0.13",
"react": "^16.0.0",
"react-dom": "^16.0.0"
}
}
I think Webpack tries to load Node packages if you don't include the relative path in your "include" lines.
Try changing this line in entry.tsx:
import menu from 'menu';
To this:
import menu from './menu';

React can't be found

index.js:
import react from 'react';
import {render} from 'react-dom';
render(
<h1>Hello World!</h1>,
document.getElementById('root')
);
package.json:
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --progress --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Callum Linington",
"license": "ISC",
"dependencies": {
"react": "^15.4.2",
"react-dom": "^15.4.2",
"whatwg-fetch": "^2.0.3"
},
"devDependencies": {
"babel-cli": "^6.24.0",
"babel-preset-es2015": "^6.24.0",
"babel-preset-react": "^6.23.0",
"babel-core": "^6.24.0",
"babel-loader": "^6.4.1",
"babel-preset-env": "^1.3.2",
"bluebird": "^3.5.0",
"eslint": "^3.19.0",
"webpack": "^2.3.2",
"webpack-dev-server": "^2.4.2"
}
}
Webpack config:
var webpack = require('webpack');
var packages = require('./package.json');
var path = require('path');
module.exports = {
entry: {
main: './src/index.js',
vendor: Object.keys(packages.dependencies)
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' // Specify the common bundle's name.
})
],
devtool: "cheap-eval-source-map",
devServer: {
contentBase: path.join(__dirname, "dist"),
publicPath: '/',
port: 9000
},
module: {
rules: [
{
test: /\.js?$/,
use: [ 'babel-loader', ],
exclude: /node_modules/
}
]
}
};
Webpack output:
Chrome Dev Output:
It is crutial to name imported React class starting with capital letter. You first line should be: import React from 'react';. That is because all JSX tags will be converted by Babel to something like React.createElement(....) and React is not there. Exactly what console output tells you.

Configure webpack for React to use multuple entries and outputs

I'm trying to config the server to have multiple entries and outputs. The app is using Zurb Foundation,jquery and React.
I want jquery and foundation not to be part of the bundle.js and also to have a separate bundle for react
Webpack validates, server starts but nothing is show and in console appears: "ReferenceError: webpackJsonp is not defined"
With a single entry is working, I don't know were is the error when trying to use multiple ones.
webpack.config
var webpack = require('webpack');
var path = require('path');
var CommonsChunkPlugin = require('./node_modules/webpack/lib/optimize/CommonsChunkPlugin');
module.exports = {
entry: {
main: ['script!jquery/dist/jquery.min.js',
'script!foundation-sites/dist/foundation.min.js',
'./dist/app.js' ],
react: ['react', 'react-dom']
},
externals: {
jquery: 'jQuery'
},
plugins: [
new webpack.ProvidePlugin({
'$': 'jquery',
'jQuery': 'jquery'
}),
new CommonsChunkPlugin('react', 'react.bundle.js')
],
output: {
filename: bundle.js'
},
devServer: {
inline: true,
contentBase: './build',
port: 3000
},
module: {
loaders: [
{
loader: 'babel-loader',
query: {
presets: ['react', 'es2015']
},
test: /\.js?$/,
exclude: /(node_modules)/
}
]
}
};
package.json
{
"name": "boilerplate",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"start": "webpack-dev-server",
"test": "karma start"
},
"author": "CBM",
"license": "MIT",
"dependencies": {
"react": "^15.3.2",
"react-dom": "^15.3.2"
},
"devDependencies": {
"babel-core": "^6.16.0",
"babel-loader": "^6.2.5",
"babel-preset-es2015": "^6.16.0",
"babel-preset-react": "^6.16.0",
"css-loader": "^0.25.0",
"foundation-sites": "^6.2.3",
"jquery": "^3.1.1",
"karma": "^1.3.0",
"karma-firefox-launcher": "^1.0.0",
"karma-mocha": "^1.2.0",
"karma-mocha-reporter": "^2.2.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.8.0",
"mocha": "^3.1.0",
"react-router": "^2.8.1",
"script-loader": "^0.7.0",
"style-loader": "^0.13.1",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.16.1"
}
}
babel.rc
{
"presets": ["es2015", "react"]
}
Specify an output for each entry:
entry: {
jquery: ['script!jquery/dist/jquery.min.js', 'script!foundation-sites/dist/foundation.min.js' ],
bundle: './dist/app.js',
react: ['react', 'react-dom']
},
output: {
filename: '[name].js'
}
If you want to add jquery and foundation libraries directly to the html just don't add the entries.
font: https://webpack.github.io/docs/multiple-entry-points.html

Categories

Resources