webpack vendor files failing on dependencies - javascript

I am trying to convert a existing dynamic web page, where everything from tables to high charts are inserted via js/html code, to be create by webpack. The js, css, images have all been modified successfully and the input files are being read in via ajax to populate the web page. The problem is the vendor js files. I am constantly getting error messages in the console about some js file function that is not defined or is not found with the 404 message. I have read the docs and reviewed existing posts for vendor, so it looks ok, but its just not working.
This is what I originally had in the html file:
<script type="text/javascript" src="js/jquery.min.1.8.2.js"></script>
<script type="text/javascript" src="js/underscore-min.js"></script>
<script type="text/javascript" src="js/react.js"></script>
<script type="text/javascript" src="js/papaparse.js"></script>
<script type="text/javascript" src="js/highcharts.js"></script>
<script type="text/javascript" src="js/modules/heatmap.js"></script>
<script type="text/javascript" src="js/modules/treemap.js"></script>
To get then imported into webpack I did the following:
index.htm (removed script type for js files since webpack will included them for me).
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="<%= htmlWebpackPlugin.options.metaDesc %>">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
index.js (this is the main file for webpack). Modules are for highchart and and load in by highchart.js.
import {readInSoftwareVersions} from "./softwareList"
import "./styles.css"
import "./vendor/js/jquery.min.1.8.2.js"
import "./vendor/js/underscore-min.js"
import "./vendor/js/react.js"
import "./vendor/js/highcharts.js"
import "./vendor/js/highcharts-more.js"
import "./vendor/js/papaparse.js"
import "./vendor/js/modules/broken-axis.js"
import "./vendor/js/modules/broken-axis.src.js"
import "./vendor/js/modules/canvas-tools.js"
import "./vendor/js/modules/canvas-tools.src.js"
import "./vendor/js/modules/data.js"
import "./vendor/js/modules/data.src.js"
import "./vendor/js/modules/drilldown.js"
import "./vendor/js/modules/drilldown.src.js"
import "./vendor/js/modules/exporting.js"
import "./vendor/js/modules/exporting.src.js"
import "./vendor/js/modules/funnel.js"
import "./vendor/js/modules/funnel.src.js"
import "./vendor/js/modules/heatmap.js"
import "./vendor/js/modules/heatmap.src.js"
import "./vendor/js/modules/no-data-to-display.js"
import "./vendor/js/modules/no-data-to-display.src.js"
import "./vendor/js/modules/solid-gauge.js"
import "./vendor/js/modules/solid-gauge.src.js"
import "./vendor/js/modules/treemap.js"
import './images/lessErrors.png'
import './images/moreErrors.png'
import './images/noChange.png'
/*
Read in software list and then build web page.
*/
$(document).ready(function(){
readInSoftwareVersions(false); // wait for json to be read in
});
webpack.config.js - I listed all the js files.
module.exports = {
mode: 'development',
entry: {
main: "./src/index.js",
vendor: [
"./src/vendor/js/jquery.min.1.8.2.js",
"./src/vendor/js/underscore-min.js",
"./src/vendor/js/react.js",
"./src/vendor/js/highcharts.js",
"./src/vendor/js/highcharts-more.js",
"./src/vendor/js/papaparse.js",
"./src/vendor/js/modules/broken-axis.js",
"./src/vendor/js/modules/broken-axis.src.js",
"./src/vendor/js/modules/canvas-tools.js",
"./src/vendor/js/modules/canvas-tools.src.js",
"./src/vendor/js/modules/data.js",
"./src/vendor/js/modules/data.src.js",
"./src/vendor/js/modules/drilldown.js",
"./src/vendor/js/modules/drilldown.src.js",
"./src/vendor/js/modules/exporting.js",
"./src/vendor/js/modules/exporting.src.js",
"./src/vendor/js/modules/funnel.js",
"./src/vendor/js/modules/funnel.src.js",
"./src/vendor/js/modules/heatmap.js",
"./src/vendor/js/modules/heatmap.src.js",
"./src/vendor/js/modules/no-data-to-display.js",
"./src/vendor/js/modules/no-data-to-display.src.js",
"./src/vendor/js/modules/solid-gauge.js",
"./src/vendor/js/modules/solid-gauge.src.js",
"./src/vendor/js/modules/treemap.js",
"./src/vendor/js/modules/treemap.src.js"
]
},
output: {
filename: "main-[contenthash].js",
path: path.resolve(__dirname, "dist")
},
plugins: [
new HtmlWebpackPlugin({
hash: true,
title: 'Unit Test Results',
metaDesc: 'Display all the test results run on the select software version',
template: './src/index.htm',
filename: 'index.htm',
inject: 'body'
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader", // 2. Inject styles into DOM
"css-loader", // 1. Turns css into commonjs
]
},
{
test: /\.(png|jpg|gif)$/,
use: {
loader: "file-loader",
options: {
name: "./images/[name].[ext]",
}
}
},
]
}
};
There are no errors on npm compile for this setup. Now I thought web pack would handle the dependencies, but I am seeing modules/canvas-tools.js saying highcharts AddEvent is not defined, papaparse.js not found, and other errors about missing or not declared. Basically the js dependencies are messed up. Moving the import order around fixes one error but then some other dependency error happens because js files in module are calling each other.
So what am I doing wrong? Do I need some plugin for vendors? Currently I dumped the vendor logic and inserted the script type lines back into index.htm so it runs, but the point was to bundle the js files together using webpack.

Instead of manually creating a vendor bundle from an entry point, you should create a so called cacheGroup for which you define a test. Here's some example code from the docs, adjusted to your situation:
module.exports = {
...
entry: {
main: "./src/index.js"
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]vendor[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
...
};
This will add all imports from the vendor directory to a chunk called vendors. You can see the full example here.

Related

Unable to import css files into NextJs project

Currently I have my index.js file that has my display components. For CSS I have downloaded a css file from an external source. I am then adding the .css file into my styles folder that comes when you make the initial npx create-next-app. This file I'm then trying to import into my index.js file like so: import bootStyles from "../styles/bootstrap.css". But doing this gives me this error:
error - ./styles/bootstrap.css Global CSS cannot be imported from
files other than your Custom . Please move all global CSS imports
to pages_app.js. Or convert the import to Component-Level CSS (CSS
Modules). Read more: https://nextjs.org/docs/messages/css-global
Location: pages\index.js
Additionally I have also tried using the Head component like so:
import Head from 'next/head'
<Head>
<title>Create Next App</title>
<link rel="stylesheet" href="../styles/bootstrap.css"/>
</Head>
This doesnt show an error but the styles still dont reflect on my webpage.
Either put all your CSS imports in _app.tsx or you can add *.module.css to your filenames so they get picked up.
You can also override the nextjs webpack config:
// next.config.js
module.exports = {
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
return config
},
}
...
{
test: /\.s?[ac]ss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
exclude: [/node_modules/],
},
In order to override the module rules and css loader, however I wouldn't recommend this if you don't know what you're doing.

Export all react components in Webpack bundle file and use in html file

I have some React components and I want to create a bundle file including them and use it in another HTML file.
What I did:
I created a Webpack config file that gets index.js in /src folder as an entry file and generates a bundle file like components.js
I exported all components in the /src/index.js file and I suppose that all of them are accessible after bundling with Webpack
I used External key in Webpack to only generate bundle file from my source, not external libs
At the end I put react and bundle file scripts in the HTML file and I want to use them as pure javascript function.
<html>
<head>
<title></title>
</head>
<body>
<header id="headerContent"></header>
<section id="newsContent"></section>
<section id="categoryContent"></section>
<footer id="footerContent" ></footer>
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script type="text/javascript" src="components.js"></script></body>
<script>
ReactDOM.render(React.createElement(HeaderComponent), document.getElementById("headerContent"))
ReactDOM.render(React.createElement(NewsComponent), document.getElementById("newsContent"))
ReactDOM.render(React.createElement(NewsComponent), document.getElementById("categoryContent"))
ReactDOM.render(React.createElement(FooterComponent), document.getElementById("footerContent"))
</script>
</body>
</html>
But it does not work. Did I something wrong and what is the best solution?
Webpack Config:
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
}
]
},
externals: {
// Don't bundle the 'react' npm package with the component.
'react': 'React',
'react-dom' : 'ReactDOM'
}
}
The simple way is assigning the component to a variable in the window object. In this way, there is no need to change the Webpack config.
window.HeaderComponent = HeaderComponent
And we can use components in other HTML files.
<script>
ReactDOM.render(React.createElement(window.HeaderComponent), document.getElementById("headerContent"))
ReactDOM.render(React.createElement(window.NewsComponent), document.getElementById("newsContent"))
ReactDOM.render(React.createElement(window.NewsComponent), document.getElementById("categoryContent"))
ReactDOM.render(React.createElement(window.FooterComponent), document.getElementById("footerContent"))
</script>

Building from quilljs source succeeds, but Quill is not found when referenced

I have managed to build quilljs from source following the steps outlined in the quilljs github repo and from the quilljs documentation. The quill version is 1.3.6. The npm run build succeeds with no errors. The problem is that whenever i want to use the built package, the module Quill is not found (like it usually does when you reference a prebuilt version from a CDN).
I have used the minimal webpack example found on the github repo. And have installed all the dependents using npm install. I have also made sure that webpack has been installed properly as per documentation. Since this didnt work, I have also tried upgrading to the newest webpack versions and newest version of typescript, ts-loader and html-loader to no avail. I still get the same issue that it cannot find Quill.
However as stated, the build succeeds with no errors or warnings.
The entry point code for the build is (using the example provided in the repo):
import Quill from "quill/core";
import Toolbar from "quill/modules/toolbar";
import Snow from "quill/themes/snow";
import Bold from "quill/formats/bold";
import Italic from "quill/formats/italic";
import Header from "quill/formats/header";
Quill.register({
"modules/toolbar": Toolbar,
"themes/snow": Snow,
"formats/bold": Bold,
"formats/italic": Italic,
"formats/header": Header
});
export default Quill;
the webpack config file (slightly modified to export the final bundle file to my app location)
var path = require("path");
module.exports = {
entry: "./app.js"),
output: {
path: __dirname + "/dist",
filename: "../../quill_app/dist/quill.js"
},
resolve: {
alias: {
parchment: path.resolve(
__dirname,
"node_modules/parchment/src/parchment.ts"
),
quill$: path.resolve(__dirname, "node_modules/quill/quill.js")
},
extensions: [".js", ".ts", ".svg"]
},
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["es2015"]
}
}
]
},
{
test: /\.ts$/,
use: [
{
loader: "ts-loader",
options: {
compilerOptions: {
declaration: false,
target: "es5",
module: "commonjs"
},
transpileOnly: true
}
}
]
},
{
test: /\.svg$/,
use: [
{
loader: "html-loader",
options: {
minimize: false
}
}
]
}
]
}
};
the index.html to run Quill from:
<!-- Create the editor container -->
<div id="editor">
<p>Hello World!</p>
<p>Some initial <strong>bold</strong> text</p>
<p><br /></p>
</div>
<!-- Include the Quill library -->
<script src="quill.js"></script>
<script src="code.js" type="module"></script>
<!-- Initialize Quill editor --
>
with the javascript part of it:
var quill = new Quill("#editor", {
theme: "snow"
});
expected result: Runs quill as normal and shows the UI
actual result: No quill is displayed. Console gives: "Uncaught ReferenceError: Quill is not defined".
Has anyone besides the devs managed to do a build based on the provided docs? It does seem a long time since the docs for the build process has been updated, but i guess not much has changed except for newer versions of the dependencies?
This does seem like a bug with Quill. Our team was able to resolve this issue by using the ProvidePlugin in our webpack.config to teach Webpack about how to resolve Quill.
import the ProvidePlugin in your webpack.config
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
then make use of the plugin within the plugins section of the config - see below for an example
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
module.exports = {
entry: '...',
output: {
...
},
module: {
rules: [
{
...
}
]
},
plugins: [
/// other plugins here
new ProvidePlugin({
"Quill": "quill"
}),
]
};
you can read more about plugins here: https://webpack.js.org/concepts/plugins/

How to bundle vendor CSS files into a React app with Webpack?

I have some 3rd party libs, like Mapbox GL, which are installed via npm and have some CSS files they rely on in their work.
As for Mapbox GL, there is mapbox-gl/dist/mapbox-gl.css in node_modules. I have index.html which is used as the entry point for my React app and contains a link to a CSS file with some defaults.
<link rel="stylesheet" href="/vendor/core.css">
All other CSS rules are provided by CSS modules, so I have a single CSS file in a React UI component folder and import it from the component like this:
import * as style from './MyComponent.css';
How do I import vendor CSS files, like Mapbox GL example above and make the rules from it apply to the app?
If your vendor css files are specific to a component, you can import them directly into your component, like this:
// Component1.js
import React from 'react';
...
import 'vendor/path/to/styles.css';
...
If you want to import a general css file (such as normalize.css), you can import them into your top-level html view. I usually have a JSX file which is transpiled by webpack to index.html. So you can do this:
// index.jsx (transpiled to index.html)
<style
dangerouslySetInnerHTML={{
__html: require('!css-loader!normalize.css/normalize.css'),
}}
/>
Or, if you have pure HTML, you can let webpack do it for you using the html-loader
For your reference, this is my webpack.config:
webpackConfig = {
module: {
rules = [
{
// excluding for node-modules
test: /.css$/,
exclude: path.resolve('./node_modules'),
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
camelCase: true,
importLoaders: 1,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
},
},
'postcss-custom-loader',
],
},
{
// only for node-modules
test: /.css$/,
include: path.resolve('./node_modules'),
use: ['style-loader', 'css-loader', 'postcss-custom-loader'],
},
...
}

import JPlayer in React component (with webpack build process)

How do I access the jPlayer object within my React component? There are many places I may be doing something wrong, so bear with...
I am developing a Redux/React web application. Starting with the scaffolding provided by the Yeoman generator, generator-redux, I have the skeleton of my app in place. This is my first encounter with webpack, having used grunt/gulp/bower in the past (though never set those up from scratch, either).
I ran npm install jquery jplayer --save so now my package.json has
"dependencies":{ ...
"jplayer": "^2.9.2",
"jquery": "^2.1.4",
...}
and the jplayer module is in the node_modules directory of my project: so far so good. But the jPlayer docs don't make the import process terribly clear, and I'm not sufficiently familiar with the whole node/webpack/babel/etc. ecosystem to be very sure of myself.
My plan is to create a React component called Player which will live in a file called Player.js in the js/components directory. How do I import the jplayer object in this scheme? I'm doing import { jPlayer} from 'jplayer' at the head of my Player.js which does not seem like it is doing what I want it to be doing, but I'm honestly a bit at a loss of how to check properly. There is no jPlayer defined in this or the top level in the console...
My imports look like this:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as PlayerActions from '../actions/PlayerActions';
import styles from '../../css/app.css';
import $ from 'jquery';
// import {jPlayer} from 'jplayer/dist/jplayer/jquery.jplayer';
import 'jplayer';
For debugging, I also added this to the Player class in Player.js
componentDidMount() {
console.log("Regulators, mount up");
console.log($('#jquery_jplayer_1'));
console.log($.jPlayer);
console.log(jPlayer)
}
which gives this output in the Chrome console:
Regulators, mount up
[div#jquery_jplayer_1, context: document, selector: "#jquery_jplayer_1"]
undefined
Uncaught ReferenceError: jPlayer is not defined
At this point, I would expect that $.jPlayer to be <jPlayer object> or some such. I want to call $('#jquery_jplayer_1').jPlayer(...) at this point, as per the docs for jPlayer.
I know I'm kind of stumbling about blindly here, with a partial knowledge of many components combining into a lot of confusion! Any guidance, and in particular a high-level view of these pieces and their interactions would be most welcome!
In case it's relevant, here's the webpack.config.js
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:3001',
'webpack/hot/only-dev-server',
'./js/index.js'
],
output: {
path: __dirname + '/static/',
publicPath: '/static/',
filename: 'bundle.js',
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
devFlagPlugin,
new ExtractTextPlugin('app.css')
],
module: {
loaders: [
{ test: /\.js$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('css-loader?module!cssnext-loader') }
]
},
resolve: {
extensions: ['', '.js', '.json']
}
};

Categories

Resources