How to use plugin to reduce size when import lodash - reactjs

Here is my code : import _ from 'lodash';
I want to use babel-plugin-transform-imports to reduce size of folder when "yarn build".
But I don't know how to set up plugin and config in wepack.config.js
Thank you so much

There is three way to reduce:
1. When in development, you can include the folder where you are going to compile by config the loaders, so the file outside this folder won't be compiled. Loader config are like the following code:
{
test: /\.(js|mjs|jsx)$/,
include: path.resolve(__dirname,"src"),//important
use: {
loader: 'babel-loader'
}
}
2、 You can use DDL to pre-compile the third-party library.
e.g.
Firstly create vendor.js, that is to say you need to bundle it by another webpack config.
const webpack = require('webpack')
const library = '[name]_lib'
const path = require('path')
module.exports = {
mode:"production",
entry: {
vendors: ['lodash']
},
output: {
filename: '[name].dll.js',
path: path.join(__dirname,"dist/vendor"),
library
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, 'dist/[name]-manifest.json'),
// This must match the output.library option above
name: library
}),
]
}
And then you need to include mainfest.json in your project webpack config:
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: path.join(__dirname, 'dist/vendors-manifest.json'),
})
]
3、 You can use externals to exclude it, you can config it like:
externals : {
lodash : {
commonjs: 'lodash',
amd: 'lodash',
root: '_' // indicates global variable
}
}
And don't forget to include lodsh script in HTML, because webpack don't compile or include it in your bundle. If you don't include ,the broswer will throw an error.
You can check more usage at Webpack website:
https://webpack.js.org/configuration/externals/
https://webpack.js.org/plugins/dll-plugin/

Related

How to use google fonts in manually created React app?

I created React app manually (not create-react-app) one by one such as index.js, App.js, index.css, components folder etc because I am using React app as a separate app in the Django project.
And in order to use google fonts, I followed this answer.
But when I write #import url('https://fonts.googleapis.com/css?family=Josefin+Sans') in the index.css, it is giving me this error.
ERROR in ./src/index.css 1:0
Module parse failed: Unexpected character '#' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> #import url('https://fonts.googleapis.com/css?family=Josefin+Sans');
|
# ./src/index.js 4:0-21
webpack 5.15.0 compiled with 1 error in 999 ms
I think this error is related to webpack.config.js and it seems I need to add some rules in the module section related to css-loader, file-loader, or something else, but I am not sure how to write.
This is just my thought, I have no idea why this is happening.
webpack.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./static/frontend"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
optimization: {
minimize: true,
},
plugins: [
new webpack.DefinePlugin({
"process.env" : {
NODE_ENV: JSON.stringify("production"),
}
})
]
};
How to solve this issue? (This issue has happened when I tried to use react-toastify also. So I removed it and used another alternative package.) How to use fonts in the non create-react-app based project?

Why CSS loader of webpack not working?

I am making the toy example described in the documentation of css-loader:
https://github.com/webpack-contrib/css-loader
I also tried this basic guide that suggest the same: https://css-tricks.com/css-modules-part-2-getting-started/
However, both VS Code highlight and when bundling through the command line complain that the module of the CSS file is not available. Like it does not really recognize it. I have checked I indeed really have installed css-loader, webpack etc. Other than the css loader, webpack is working fine for javascript, typescript etc. So it is really just a problem with CSS. Any ideas why failing?
The error I get is:
TS2307: Cannot find module 'styles.css'.
My file:
import test from 'styles.css';
I tried also without file extension, with and without curly braces etc. But really followed the toy example in the docu of css-loader.
My webpack.config file:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const config = {
entry: "./src/index.tsx",
resolve: {
extensions: ['.tsx', '.js', '.css']
},
output: {
filename: "bundle.js",
},
plugins: [
new HtmlWebpackPlugin({
title: 'title Cool!',
}),
],
module: {
rules: [
{
test: /.tsx$/,
loader: "ts-loader" ,
},
{
test: /.css$/,
use: [ 'style-loader', 'css-loader' ],
}
]
}
}
module.exports = config;
Any ideas?
Are you sure you need a named import? This should work: import './styles.css';.
The problem was related to typescript and not to webpack or the css loader.
So I needed to add css files to modules for typescript:
declare module '*.css' {
const content: any;
export default content;
}
Did the trick. No clue why this is not mention in any of the dozens of tutorial and guides I saw.
You should provide a relative path to your file:
import test from './path/to/styles.css';

Webpack bundle JS without React or React Dom

I'd like to use webpack to bundle my JS together for a React component but without including React or React Dom, just my own React code.
The idea is so that I can load React or React Dom separately on the webpage with RequireJS as I'm adding the component to Magento2 which uses this approach for adding JS dependencies. My thought being that if I add another component this way, I don't want to be adding the React Libraries twice.
I think I need to use a different babel loader or pass in some other options?
Here is my webpack.config
const path = require('path');
const autoprefixer = require('autoprefixer');
const webpack = require('webpack');
module.exports = {
devtool: 'cheap-module-source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'web'),
filename: 'js/react-component.js',
publicPath: ''
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
}
It works but as I said it includes the full react libraries in the generated js/react-component.js file. Any advice how I can do this?
As #Aaqib pointed out I needed to add this config options to webpack.
externals : {
react: 'react',
reactDom: 'react-dom'
}

Importing materialdesignicons package in ReactJS & Webpack

I am trying to add material design icons into my project via the npm "mdi" package. but I have issues.
webpack.config.js
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'src/public');
var APP_DIR = path.resolve(__dirname, 'src');
var config = {
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080/',
APP_DIR + '/index.jsx'
],
output: {
path: BUILD_DIR,
filename: 'bundle.js',
publicPath : '/'
},
devServer : {
historyApiFallback: true,
contentBase: 'src/public/'
},
module: {
loaders : [
{
test : /\.jsx?/,
include : APP_DIR,
loader : ['react-hot-loader', 'babel-loader']
},
{
test: /\.s?css$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
},
{
test: /\.(eot|svg|ttf|woff|woff2)(\??\#?v=[.0-9]+)?$/,
loader: 'file-loader?name=/fonts/[name].[ext]',
}
]
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
],
resolve: {
extensions: ['.js', '.jsx']
}
};
//dev server
module.exports = config;
my App components calls the main scss file
import './scss/App.scss';
then in that App.scss file, I import a settings.scss and the materialdesignicons.scss file
settings.scss
$mdi-font-path: "fonts/";
App.scss
#import "./settings.scss";
#import '~mdi/scss/materialdesignicons.scss';
the project is imported via the main.scss file.
settings.scss
$mdi-font-path: "fonts/";
whenever I try to build, I get an error with it trying to figure out how to handle the webfont items.
ERROR in ./~/css-loader!./~/sass-loader!./src/scss/App.scss
Module not found: Error: Can't resolve './fonts//materialdesignicons-webfont.eot?v=1.9.32' in '/<path>/app/src/scss'
# ./~/css-loader!./~/sass-loader!./src/scss/App.scss 7:129-189
# ./src/scss/App.scss
# ./src/App.jsx
# ./src/index.jsx
# multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server webpack-dev-server/client?http://localhost:8080/ ./src/index.jsx
I thought that the file-loader would handle those files. It seems that maybe since it's importing the scss file, it doesn't use the file loader part, and instead tries to use the sass/css loaders.
I'm trying to figure out how this should be done.
My approach consists of three steps:
to install material-design-icons package
npm install material-design-icons
to import material-icons.css file into .less or .scss file/ project
#import "~/node_modules/material-design-icons/iconfont/material-icons.css";
to include recommended code into the reactjs .js file/ project
<i className='material-icons' style={{fontSize: '36px'}}>close</i>
The file-loader does hadle those files. The Issue you have is that the file could not be found, and therefore it never gets to the file-loader.
materialdesignicons-webfont.eot is part of your node_modules, but when I think right now it is expected to be at ./app/src/scss/fonts/materialdesignicons-webfont.eot
I would expect this to work if you just remove your own definiton of $mdi-font-path.
UPDATE:
$mdi-font-path: '~mdi/fonts/';
#import '~mdi/scss/materialdesignicons';

React webpack create bundle with separated react

is possible to configure webpack to not compile react inside bundle file? I would like to have more react applications in one page and I would like to load react library only once to get smallest size. How to achieve this?
In same situation I created final bundle with all small "applications" + React bundled once.
// components/index.js (webpacks entry point)
require("expose?React!react");
require("expose?MarketProductListing!./MarketProductListing");
require("expose?ProductDetail!./ProductDetail");
require("expose?MarketSearch!./MarketSearch");
Then, I include bundled JS via <script/> tag.
<script src="js/components.bundle.js"></script>
Now, I can access React, MarketProductListing, ... components in JS and render them where needed.
As you see, I use expose-loader for Webpack.
Webpack config
var path = require('path');
var webpack = require('webpack');
const js_dir = path.join(__dirname, 'src');
module.exports = {
devtool: 'eval',
entry: {
components: path.join(js_dir, 'components'),
},
output: {
path: js_dir,
filename: '[name].bundle.js'
},
plugins: [
new webpack.ProvidePlugin({
'es6-promise': 'es6-promise',
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
})
],
module: {
loaders: [
{ test: /\.js$/, loaders: ['babel'] }
]
},
resolve: {
extensions: ['', '.js', '.json']
}
};

Resources