Redundant Modules in Webpack Dllplugin - javascript

I am using Webpack 3.0.0 for my application. I am trying to split my references to libraries in to separate files using the DllPlugins in Webpack. Initially I was using CommonsChunkPlugin which allowed me to split my libraries as jquery.js and kendo.js . The kendo.js file did not contain the jquery library.
After I changed this using DllPlugin, it seems both jquery.js and kendo.js have jquery.
Below is my configuration
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
jquery: ["jquery"],
kendo: [
'kendo.autocomplete.min',
'kendo.treelist.min',
'kendo.slider.min',
'kendo.tooltip.min',
'kendo.dataviz.chart.min',
'kendo.dataviz.themes.min',
'kendo.grid.min',
'kendo.data.min',
'kendo.core.min'
]
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, '../assets'),
library: "[name]_lib"
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(__dirname, '../assets/[name]-manifest.json'),
name: '[name]_lib'
})
],
};
Could someone please help change the configuration to exclude jquery from kendo.js .

Related

Webpack with requirejs/AMD

I'm working on a new module for an existing project that still uses requireJS for module loading. I'm trying to use new technologies for my new module like webpack (which allows me to use es6 loaders using es6 imports). It seems like webpack can't reconcile with requireJS syntax. It will say things like: "Module not found: Error: Can't resolve in ".
Problem: Webpack won't bundle files with requireJS/AMD syntax in them.
Question: Is there any way to make webpack play nice with requireJS?
My final output must be in AMD format in order for the project to properly load it. Thanks.
I had the same question and I managed to achieve it. Below is the same webpack.config.js file.
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
let basePath = path.join(__dirname, '/');
let config = {
// Entry, file to be bundled
entry: {
'main': basePath + '/src/main.js',
},
devtool: 'source-map',
output: {
// Output directory
path: basePath + '/dist/',
library: '[name]',
// [hash:6] with add a SHA based on file changes if the env is build
filename: env === EnvEnum.BUILD ? '[name]-[hash:6].min.js' : '[name].min.js',
libraryTarget: 'amd',
umdNamedDefine: true
},
module: {
rules: [{
test: /(\.js)$/,
exclude: /(node_modules|bower_components)/,
use: {
// babel-loader to convert ES6 code to ES5 + amdCleaning requirejs code into simple JS code, taking care of modules to load as desired
loader: 'babel-loader',
options: {
presets: ['es2015'],
plugins: []
}
}
}, { test: /jQuery/, loader: 'expose-loader?$' },
{ test: /application/, loader: 'expose-loader?application' },
{ test: /base64/, loader: 'exports-loader?Base64' }
]
},
resolve: {
alias: {
'jQuery': 'bower_components/jquery/dist/jquery.min',
'application': 'main',
'base64': 'vendor/base64'
},
modules: [
// Files path which will be referenced while bundling
'src/**/*.js',
'src/bower_components',
path.resolve('./src')
],
extensions: ['.js'] // File types
},
plugins: [
]
};
module.exports = config;

Optimal webpack.config with webpack 2 for AngularJS 1.x app?

I want to set up an Angular 1.x app from scratch using webpack 2.
I am having trouble finding the best configuration for webpack.config, with optimal entry and output for production (meaning, all code, style and templating minified and gziped with no code repetition).
My main problem is how to set up webpack.config so that it recognizes all partials within the folder structure of my project, like these:
My current config file, for reference (which can't see subfolders):
var HtmlWebpackPlugin = require( 'html-webpack-plugin' );
var ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
var path = require( 'path' );
module.exports = {
devServer: {
compress: true,
contentBase: path.join( __dirname, '/dist' ),
open: true,
port: 9000,
stats: 'errors-only'
},
entry: './src/app.js',
output: {
path: path.join( __dirname, '/dist' ),
filename: 'app.bundle.js'
},
module: {
rules: [ {
test: /\.scss$/,
use: ExtractTextPlugin.extract( {
fallback: 'style-loader',
use: [
'css-loader',
'sass-loader'
],
publicPath: '/dist'
} )
} ]
},
plugins: [
new HtmlWebpackPlugin( {
hash: true,
minify: { collapseWhitespace: true },
template: './src/index.html',
title: 'Prov'
} ),
new ExtractTextPlugin( {
filename: 'main.css',
allChunks: true
} )
]
};
Note that this isn't an exhaustive solution, as there are many optimizations one can make in the frontend, and I've kept the code snippets fairly short.
With webpack, there are a few routes that you can take to include partials into your app.js.
Solution 1
You can import/require your partials within app.js as such:
app.js
var angular = require('angular');
var proverbList = require('./proverb/list/proverb.list');
// require other components
// set up your app as normal
This allows the app.bundle.js to include your component js files in the main bundle. You can also use html-loader to include templates in the final bundle.
This isn't ideal, as all it does is create a large bundle.js (which doesn't leverage multiple downloads with http2 nor does it allow loading of components/files when the user explicitly requires it).
Solution 2
Importing partials as separate entry files into your webpack bundle:
webpack.config.js
const globby = require('globby');
const sourceDir = 'src';
var webpackentry = {
app: `${__dirname}/src/app.js`
};
const glob = globby.sync(`${__dirname}/${sourceDir}/**/*.js`)
.map((file)=>{
let name = file.split('/').pop().replace('.js', '');
webpackentry[name] = file;
});
const config = {
entry: webpackentry,
...
}
The second solution is unorthodox but it can be useful if you wanted to split all your partials as <script> tags in your html (for example if your company/team uses that as a means to include your directive/components/controllers), or if you have an app-2.bundle.js.
Solution 3
Use CommonsChunkPlugin:
webpack.config.js
let webpackentry = {
vendor: [
'module1',
'module2',
'module3',
]
}
...
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor'] //... add other modules
})
]
CommonsChunkPlugin allows webpack to scrawl through your entry files and discern common modules that are shared among them. This means that even if you are importing module1 in different files, they will be compiled only once in your final bundle.

Concat and minify CSS files with Webpack without requiring them from JS

what I'd like to achieve is the simplest way to concat and minify CSS with Webpack. I (successfully) tried ExtractTextPlugin and OptimizeCssAssetsPlugin, as follows
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: {
app: "./assets/js/main.js"
},
output: {
path: 'dist',
filename: "main.bundle.js"
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin({
filename: "style.min.css",
allChunks: true
}),
new OptimizeCssAssetsPlugin()
]
}
But this only works requiring CSS files from within JS file, like that
require("../../css/normalize.css");
require("../../css/modal.css");
I would like JS files had nothing to do with CSS files.
My question is: how can I avoid requiring CSS file from JS entry point, and thus how can I specify in webpack.config.js what CSS file to concat and minify? So I want to write in webpack.config.js something like "i want to concat and minify all CSS files contained in /assets/css/ folder".
Thank you

Webpack with Thridparty bundle

i want to provide a webpack bundle which contains all common thirdparty vendors(angular 1.4, jQuery, and some other libs).
Currently the follow modules are developed
Module A
Vendor Module
Vendor Module:
Create a simple module with all thridparty libs(angular 1.4, jQuery, and some other libs)
webpack.config.js:
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
vendor: './index.js',
},
output: {
// filename: '[chunkhash].[name].js',
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: []
}
index.js:
require('jquery');
require('angular');
Module A:
index.js:
var angular = require('angular');
var myJQ = require('jQuery');
var app = angular.module("Test", []);
console.log("Angular Boostrap");
console.log(app);
console.log("jQuery Boostrap");
console.log(myJQ);
webpack.config.js:
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
main: './index.js',
},
externals: {
angular: 'angular',
"jQuery": {
root: '$',
commonjs: 'jquery',
amd: 'jquery'
}
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: []
}
Module A index.js can require 'angular' and i see the right output, but the require from 'jquery' failed with an error.
There a two questions in my mind.
Which is common way to include third party vendors?
Whats wrong with jquery in the Module A index.js
Thank you.
The best way to include third party vendors is the DllPlugin. It does exactly what you want, splitting your app in two bundles. That way the build process is fast, independent and you have no limits in your app, because the dllPlugin connects both bundles. Sadly, there is no documentation about the dllPlugin in the webpack v2 documentation yet, but there are tutorials around, like https://robertknight.me.uk/posts/webpack-dll-plugins/
I think it depends on which jQuery you use. If jQuery exposes itself onto the window automatically, try
externals: { jQuery: 'window.jQuery' }

How to require 'ace-builds/ace' with Webpack and noParse option

I'm currently trying to require ace-builds (installed from bower) with webpack. Since it's a huge lib, I'm adding the whole folder to noParse option. I'm running webpack with -d option on terminal.
The problem is: when my code tries to require it, it is an empty object. Also, it's not loaded by the browser. Here are some information of what I'm doing:
My file:
// custom_editor.js
// ace-builds are aliased by ace keyword
var Ace = require('ace/ace'); // This is an empty Object when I'm debugging with breakpoints
Config file:
// webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
form: path.join(__dirname, 'static/main_files/form.js'),
vendor: [
'jquery',
'react',
'underscore',
'query-string',
'react-dnd',
'react-select-box'
]
},
output: {
path: path.join(__dirname, 'static/bundle'),
filename: '[name].bundle.js'
},
module: {
loaders: [{
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM'
}],
noParse: [
/ace-builds.*/
]
},
resolve: {
extensions: ['', '.js', '.jsx'],
root: [
__dirname,
path.join(__dirname, 'static'),
path.join(__dirname, 'node_modules')
],
alias: {
jQueryMask: 'node_modules/jquery-mask-plugin/dist/jquery.mask',
twbsDropdown: 'node_modules/bootstrap-sass/assets/javascripts/bootstrap/dropdown',
'twbs-datetimepicker': 'node_modules/eonasdan-bootstrap-datetimepicker/src/js/bootstrap-datetimepicker',
ace: 'bower_components/ace-builds/src',
'select-box': 'node_modules/react-select-box/lib/select-box',
queryString: 'node_modules/query-string/query-string',
moment: 'node_modules/moment/moment'
}
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
};
It was not loaded on Chrome's Network panel
It is showing on Chrome's Sources panel (Don't know why because no ace.map file were loaded either)
Really running out of ideas of what I'm doing wrong here. Is there any good example that I can clone and test? (It can be another lib as well).
Use brace. It's a browserify compatible version of the ace editor which also works with webpack. Version 0.5.1 is using ace 1.1.9.
https://github.com/thlorenz/brace

Categories

Resources