I have the following webpack configuration file, where I'm trying to make two bundle files for two separate projects:
var webpack = require('webpack');
var path = require('path');
var INDEX_BUILD_DIR = path.resolve(__dirname, 'src/client/app/public');
var INDEX_APP_DIR = path.resolve(__dirname, 'src/client/app/');
var RESULTS_BUILD_DIR = path.resolve(__dirname, 'src/client/results/public');
var RESULTS_APP_DIR = path.resolve(__dirname, 'src/client/results/');
var config = {
entry: {
INDEX_BUILD_DIR: INDEX_APP_DIR,
RESULTS_BUILD_DIR: RESULTS_APP_DIR
},
output: {
path: './',
filename: '[name].js'
},
module : {
loaders : [
{
test : /\.jsx?/,
include : [INDEX_APP_DIR, RESULTS_APP_DIR],
loader : 'babel'
}
]
}
};
module.exports = config;
I made this structure after looking here:
https://github.com/webpack/webpack/issues/1189
However, I am getting this issue:
ERROR in Entry module not found: Error: Cannot resolve 'file' or 'directory' path/to/project/src/client/app in /path/to/project
I can't understand where the issue originates from.
Also, only one file is created named "RESULTS_BUILD_DIR.js" which means that a variable is interpreted literally.
What causes these problems?
There are 2 things:
Error in entry: you're pointing a path to module, so you have to have an index.js file in path/to/project/src/client/app as well as in src/client/results/
RESULTS_BUILD_DIR.js yes, this notation filename: '[name].js' says "put the name of the entry and add dot and js - and this would be a result filename"
Related
I have a question for you - how is it possible to implement multi-file compilation while preserving the tree of folders and documents, while not writing each file into entry in this way
entry: {
index:'./src/index.ts',
'bot/main':'./src/bot/main.ts'
}
But at the same time, the files had their names and their position, as before compilation in js, only instead of the src folder, they were in the dist folder?
My current config webpack.config.js
const path = require('path')
const nodeExternals = require('webpack-node-externals')
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')
module.exports = {
context: __dirname,
entry: {
index:'./src/index.ts',
'bot/main':'./src/bot/main.ts'
},
externals: [nodeExternals()],
module: {
rules: [
{
exclude: /node_modules/,
test: /.ts$/,
use: {
loader: 'ts-loader'
}
}
]
},
node: {
__dirname: false
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [
new TsconfigPathsPlugin({
baseUrl: './src'
})
]
},
output: {
filename: '[name]js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/'
},
target: 'node'
}
And when building in production mode, all this was compiled into one file, taking into account all URLs, imports, etc.
Is it even possible?
Webpack itself won't do that for you. You will need to write litter helper function to achieve this. The basic idea is to crawl the directory, find all the files and then provide them to Webpack:
const path = require('path');
const glob = require('glob');
const extension = 'ts';
// Recursively find all the `.ts` files inside src folder.
const matchedFiles = glob.sync(`./src/**/*.${extension}`, {
nodir: true
});
const entry = {};
matchedFiles.forEach((file) => {
const SRC_FOLDER = path.join(__dirname, 'src');
const ABS_PATH = path.join(__dirname, file);
// Generates relative file paths like `src/test/file.ts`
const relativeFile = path.relative(SRC_FOLDER, ABS_PATH);
// fileKey is relative filename without extension.
// E.g. `src/test/file.ts` becomes `src/test/file`
const fileKey = path.join(path.dirname(relativeFile), path.basename(relativeFile, extension));
entry[fileKey] = relativeFile;
});
module.exports = {
context: __dirname,
// Use the entry object generated above.
entry,
// ... rest of the configuration
};
why doesn't webpack support static field?
When i try
export class Game {
#lasttime = 0;
#FRAME_DURATION = 1000 / 144;
I get an error
Module parse failed: Unexpected character '#' (2:4)
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.
What is the problem?
const path = require('path');
const HTMLPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/main.js',
path: path.resolve(__dirname, 'dist'),
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
plugins: [
new HTMLPlugin({
template: './src/index.html'
})
],
};
https://webpack.js.org/guides/getting-started/#modules:
Note that webpack will not alter any code other than import and export statements. If you are using other ES2015 features, make sure to use a transpiler such as Babel or Bublé via webpack's loader system.
You need to configure babel-loader yourself, see https://webpack.js.org/loaders/babel-loader/#root
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 .
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.
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' }