How to merge bundles with webpack - javascript

I'm developing a few React components with the intention of adding them to our Webflow site. For that, I've added an entry for each component in my webpack.config.js file. Now, it looks like this:
const path = require("path");
module.exports = {
entry: {
component_a: "./src/components/a.js",
component_b: "./src/components/b.js",
component_c: "./src/components/c.js",
},
mode: "production",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(pdf|jpg|png|gif|svg|ico)$/,
use: [
{
loader: "url-loader"
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: "file-loader"
}
]
},
resolve: {
extensions: ["*", ".js", ".jsx"]
},
output: {
path: __dirname + "/dist",
publicPath: "/",
filename: "bundle_[name].js"
},
devServer: {
static: {
directory: path.join(__dirname, "dist")
}
}
};
This generates me a few bundle_<component_name>.js files, which works great!
But then, there was a need of adding react-map-gl for some of those components, and that's where the issue began: I was having an issue with react-map-gl when doing npm run build and this solved it. But at the same time, a new bundle_mapbox-gl-csp-worker.worker.js is generated for me and all of my built components that depend on it have something like this:
{return new Worker(i.p+"bundle_mapbox-gl-csp-worker.worker.js")}
Although it works fine for our container deployment (because it will always look for bundle_mapbox-gl-csp-worker.worker.js on the same origin and this file will exist), whenever I try to add <script src="https.../bundle_my_component.js"> to Webflow, it will look for https://my-webflow.domain/bundle_mapbox-gl-csp-worker.worker.js, which doesn't exist.
I've tried to replace i.p+"bundle_mapbox-gl-csp-worker.worker.js" to somewhere this script is known to exist, but then I get Script at 'https://.../bundle_mapbox-gl-csp-worker.worker.js' cannot be accessed from origin 'https://some.other.origin'.
I wonder if there's a way of merging my component and the bundle_mapbox-gl-csp-worker.worker.js somehow, either through webpack or something. Or any other workaround for this.

Related

Webpack configuration vs multiple bundles and ordering

I have a big javascript (angularjs) application which I have bootstrapped in a Angular 8 project. Now I also have many vendor libraries that are javascript files. For example Kendo libs, JQuery, foundation (zurb).
I have these vendor files, and my app files included in my webpack configuration. Which looks like this:
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
'ang': './chunks/angularjs.ts',
'fou': './chunks/foundation.ts',
'ken': './chunks/kendo.ts',
'vws': './chunks/views.ts',
'dir': './chunks/directives.ts',
'ser': './chunks/services.ts',
'con': './chunks/controllers.ts',
'app': './main.ts',
'toastr': './app-old/scripts/toastr.js'
},
output: {
path: helpers.root('dist/dev'),
publicPath: '/',
filename: '[name].bundle.js'
},
// Currently we need to add '.ts' to the resolve.extensions array.
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
// Add the loader for .ts files.
module: {
rules: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader?keepUrl=true'],
exclude: [/\.(spec|e2e)\.ts$/]
},
{
test: /\.less$/,
loader: 'less-loader', // compiles Less to CSS
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|tff|otf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[hash].[ext]'
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
// Exposes jQuery for use outside Webpack build
test: require.resolve(path.resolve(__dirname, './app-old/scripts/jquery-2.1.4.js')),
use: [{
loader: 'expose-loader',
options: 'jQuery'
}, {
loader: 'expose-loader',
options: '$'
}]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: '../config/index.html'
}),
// new webpack.ProvidePlugin({
// foundation: 'foundation-sites/js/foundation/foundation'
// }),
new webpack.ProvidePlugin({
$: path.resolve(__dirname, './app-old/scripts/jquery-2.1.4.js'),
jQuery: path.resolve(__dirname, './app-old/scripts/jquery-2.1.4.js'),
"window.jQuery": path.resolve(__dirname, './app-old/scripts/jquery-2.1.4.js')
}),
new webpack.ProvidePlugin({
toastr: 'toastr',
"window.toastr": "toastr"
})
]
}
You see that I have created different entry points, because I want smaller chunks (because of performance).
It compiles perfectly, but when I start up the application the troubles begin. I get al kinds of erros. It keeps telling my that JQuery needs to be loaded before Kendo is being loaded. And the foundation files need don't see the JQuery files.
But I made sure that they are globally available, as you can see in the file.
Not the strange thing.
When I throw everything in 1 TS file and use just only 1 entry point everything runs ok and I have no errors. :-)
But then my bundled file is huge and this is not good for the performance.
So my main question is?
How can I get multiple chunks for my vendor javascript files so that they can see each other?
I am starting to think that I don't need to use the entry points for smaller chunks.

Require not defined in script tag

I am writing an electron app using react as for the UI and webpack for bundling. Webpack is configured right now for the react part of the application as follows:
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
mode: 'development',
entry: './src/index.tsx',
target:'node',
output: {
filename: '[name].bundle.js',
path: path.join(__dirname, 'build')
},
module: {
rules: [
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: {
loader: 'ts-loader'
}
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader'
}
]
},
{
test: /\.css$/,
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
test: /\.scss$/,
use: [{
loader: "css-loader", options: {
sourceMap: true
}
}, {
loader: "sass-loader", options: {
sourceMap: true
}
}]
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
plugins: [
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html"
}),
new CopyWebpackPlugin([{ from: 'public',ignore: ['*.html'] }])
],
devtool: 'eval-source-map'
}
In my index.html I need to use the following script tag for electron's rendering process :
<script>
require('build/bundle.js')
</script>
When I run webpack-dev-server everything compiles without error, but when I open chrome dev tools I see this error :
Uncaught ReferenceError: require is not defined
at (index):12
I had to target node in my webpack.config to make electron work so I assume the require function works in browser as well since if I were to create an electron app in a pure node.js environment(without webpack and react) it works without any additional configuration. So I guess there is an issue with my webpack configuration, but I can't find any useful resource online unfortunately. Can anyone help me out? Thanks in advance!
Electron is basically a chromium browser connected to a node process through « IPC ».
This means you don’t have require available in the browser.
You need to import your script like this:
<script src="/build/bundle.js"></script>
And also you need to change the target from node to electron-renderer for the browser code.
If you also need to build code for the node side you need to add the electron-main target.
See https://webpack.js.org/configuration/

configure Laravel mix mix.webpackConfig({}) with entry points and outputs

I'm developing an application that use php 5.6 and laravel 5.4. I'm using laravel mix for build my assets. I need to know how to use mix.webpackConfig({}) method to use another webpack configurations like use babel-loader, riot-tag-loader etc. Is there any way to use this method to do that with entry point and output files? For an example, I need to do following thing inside my mix.webpackConfig({}).
module.exports = {
entry: {
admin: ['./resources/assets/admin/js/app.js'],
'manuals/parent/child/js': ['./resources/views/manuals/parent/child/js/app.js']
},
output: {
filename: '[name]/app.js',
path: path.resolve(__dirname + '/public')
},
module: {
rules: [
{
test: /\.tag$/,
exclude: /node_modules/,
loader: 'riot-tag-loader',
query: {
type: 'es6',
hot: true
}
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
};
Is that possible? Is that so, please let me know how to do that. Thanks
I've hardly found the laravel-mix mix.webpackConfig({}) successfully initiated, and even working samples are rear. I do not know what framework you are trying to manage but this sample works; this is a config for less-loader, hope you can tune it to suit your purpose.
const path = require('path');
mix.webpackConfig({
module: {
rules: [
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
exclude: [
path.resolve(__dirname, "node-modules"),
path.resolve(__dirname, "resources/assets/less"),
],
},
]}
})
Mix is a configuration layer on top of Webpack, so to run your Mix tasks you only need to execute one of the NPM scripts that is included with the default Laravel package.json file: more details in official site
https://laravel.com/docs/5.7/mix

How to customize webpack build script for React App

I am moving a web app to react, therefore and moving from Grunt as a buildtool over to webpack. Right now, the below code is the webpack.config file. This is set up as recommended for developing and then has a build script (npm run and npm build)
However, the build script now only concatenates the components/react js files and puts them at the root of the dist folder. No other files are copied over. I don't understand the point of the build script if that's all it does. But I need to be able to add that in, however, no resource with reacts build scripts shows how you would go about that
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./app/src/components/app.js",
output: {
path: path.join(__dirname, "/dist"),
filename: "index_bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./app/index.html"
})
]
};
you do not need a '/'
output: {
path: path.join(__dirname, "dist"),
filename: "index_bundle.js"
},

Correctly bundled image could not be loaded

I have a very simple React component, that is supposed to display an image.
I am also using Webpack for bundling.
It's probably worth noting that I am using ReactJS.NET.
Although the webpack bundle builds properly, and the .jpg generated by webpack is viewable (using Windows Photo Viewer, for example), the image does not display in my View.
When I take a peek into inspector, the html structure is built properly, but I am getting:
"Could not load the image" - when I hover over the image path.
I made sure that the image path is correct.
Below is my react component:
var React = require('react');
var BackgroundImg = require('./Images/img_fjords.jpg');
class Login extends React.Component {
render() {
return (
<img src={BackgroundImg} />
);
}
componentDidMount() {
console.log("Mounted");
}
}
module.exports = Login;
Webpack config:
var path = require('path');
var WebpackNotifierPlugin = require('webpack-notifier');
module.exports = {
context: path.join(__dirname, 'App'),
entry: {
server: './server',
client: './client'
},
output: {
path: path.join(__dirname, 'Built/'),
publicPath: path.join(__dirname, 'Built/'),
filename: '[name].bundle.js'
},
plugins: [
new WebpackNotifierPlugin()
],
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff"
},
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" },
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' },
{ test: /\.jsx$/, loader: 'jsx-loader?harmony' }
]
},
resolve: {
// Allow require('./blah') to require blah.jsx
extensions: ['.js', '.jsx']
},
externals: {
// Use external version of React (from CDN for client-side, or
// bundled with ReactJS.NET for server-side)
react: 'React'
}
};
The problem was solved thanks to help from #Luggage.
The webpack.config was wrong, it should have been:
output: {
path: path.join(__dirname, 'Built/'),
publicPath: 'Built/',
filename: '[name].bundle.js'
},
Well, I can't see your webpack config, but I'm assuming your using all the correct loaders (file-loader, extract-loader, html-loader, url-loader)? The way I handle it is using the webpack-copy-plugin to copy over my images folder so relative paths still work.

Categories