Reputation: 81
I'm new on Webpack world.
I followed some tutorial and I set a new Webpack installation on my Wordpress theme folder and everything work fine.
My idea was to build 2 js. One for my custom js scripts (public.js) and one where include all the third party library (vendor.js)
Now I start to write code about my new theme and I need to include some third party library.
For exemple chartjs.js that use Chart command for start a new graphic chart istance.
In my webpack.config.js file I created two entry point:
vendor: [array of 3rd js library],
public: './src/js/public.js'
but in console I get the referenceError: Chart is not defined.
I understood that I need to import the library inside the main js (public.js), but in this way Webpack build the public.js with the full Chart library codes inside the file where I write my custom scripts and at this point vendor.js doesn't have sense to exists.
So here my question.
There is a way to have the third party library inside the vendor.js and have my custom scripts inside public.js without import the js library in the public.js?
Those are my files with the import fuctions:
Webpack.config.js
const path = require('path');
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const modeConfig = env => require(`./configs/${env.mode}.js`)(env);
module.exports = env => {
return webpackMerge(
{
mode: env.mode,
entry: {
vendor: ['./node_modules/jquery/dist/jquery.min.js','./node_modules/lottie-web/build/player/lottie.min.js'],
public: './src/js/public.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'assets/js/')
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
},
{
test: /\.(png|jpe?g|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '/[name].[ext]',
outputPath: '../../assets/img',
},
}
],
},
],
},
resolve: {
alias: {
charts: path.resolve(__dirname, 'node_modules/lottie-web/build/player/lottie.min.js'),
}
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
new CleanWebpackPlugin(),
]
},
modeConfig(env),
)
};
Package.json
{
"name": "wolftrick",
"version": "1.0.0",
"description": "Package file for Wolftrick website",
"scripts": {
"dev": "webpack --watch --env.mode development",
"build": "webpack -p --env.mode production"
},
"author": "Wolftrick",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.5.4",
"@babel/preset-env": "^7.5.4",
"autoprefixer": "^9.6.1",
"babel-loader": "^8.0.6",
"browser-sync": "^2.26.7",
"browser-sync-webpack-plugin": "^2.2.2",
"bulma": "^0.7.5",
"clean-webpack-plugin": "^3.0.0",
"cross-env": "^5.2.0",
"css-loader": "^3.0.0",
"file-loader": "^4.1.0",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"url-loader": "^2.1.0",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.6",
"webpack-dev-server": "^3.7.2",
"webpack-merge": "^4.2.1"
},
"browserslist": [
"> 0.5%",
"last 2 versions",
"Firefox ESR",
"android 4",
"opera 12",
"ie >= 10",
"ie_mob >= 10",
"ff >= 30",
"chrome >= 34",
"safari >= 7",
"opera >= 23",
"ios >= 7",
"android >= 4.4",
"bb >= 10",
"not dead"
],
"dependencies": {
"jquery": "^3.4.1",
"chart": "^2.8.0"
}
}
public.js
import '../scss/style.scss';
import Chart from 'charts';
'use strict';
var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
With this code Chart work perfectly, but I have all the Chart.js code inside the public.js (and I guess there isn't any reason to have the library in the vendor entry point).
I hope there is a way to have all the chart.js code inside vendor.js and have the chance to call the Chart istance in the public.js without import the full library.
Thank you very much and I hope I explained myself well because of my bad English.
Upvotes: 1
Views: 846
Reputation: 4123
externals: { chart: 'Chart' },
<canvas id="myChart" width="400" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
let ctx = document.getElementById('myChart'); let myChart = new Chart(ctx, {
type: 'bar',...
An example of using the chart.js library -> look
I misunderstood your question. You do not need to add vendor to entry. I will give an example.
I have three files.
a.js
import Chart from 'chart.js';
let ctx = document.getElementById('myChart');
let myChart = new Chart(ctx, {
type: 'bar',
...
b.js
import Chart from 'chart.js';
import $ from "jquery";
let ctx = document.getElementById('myChart');
let myChart = new Chart(ctx, {
type: 'bar',
...
c.js
console.log('next site');
webpack.config.js
entry: {
pagea: './a.js',
pageb: './b.js',
pagec: './c.js'
},
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
},
As a result you will have:
pagea.js
pageb.js
pagec.js
vendors~pagea~pageb.js // chart.js for pagea + pageb
vendors~pageb.js // jquery for pageb
More SplitChunksPlugin
Upvotes: 1