I am new to webpack & want to add all the css files bundled and added to to the index.html file in dist.
my webpack.config.js file
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const helpers = require('./helpers');
module.exports = function(env) {
return {
entry: {main:'./app/index.js',
vendor: 'moment'
},
resolve: {
extensions: ['.css', '.js']
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
include: helpers.root('app'),
use: ExtractTextPlugin.extract({
fallback: "css-loader",
use: 'style-loader'
})
},
{
test: /\.html$/,
loader: 'html-loader'
}
]},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', , 'manifest']
}),
new ExtractTextPlugin('styles.css'),
new HtmlWebpackPlugin({
template: 'app/index.html',
inject: 'body'
})
]
}
};
However it does not create styles.css file.
Thanks in advance.
Related
I would like to divide my scss styles into chunks. Therefore, I created a separate subpage.scss imported by subpage.js file (one of the entries). I use miniCssExtractPlugin to extract SCSS styles from JS and create style bundles for each file. I map them in my BundleConfig to specific style chunks referenced in HTML.
The whole process works for the main.js and main.scss but not for subpage.js and subpage.scss - it leaves styles in .js file and the styles are loaded twice (both from JS and from HTML). The only difference between these cases is that the main.js is loaded as an entry in webpack.config.js and subpage.js is loaded with the remaining entries in webpack.DefinePlugin().
Any idea why MiniCssExtractPlugin doesn't extract the styles from a .js file loaded using this method and extracts styles for the main entry correctly?
My webpack.config.js
const readEntries = require('./entries');
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const entries = readEntries('../Scripts/entries');
module.exports = (mode) => ({
name: 'name',
context: path.resolve(__dirname, '../Scripts'),
resolve: {
extensions: ['.js', '.json', '.html', '.vue'],
alias: {
'~': path.resolve(__dirname, '../Scripts'),
'vue$': 'vue/dist/vue.esm.js',
'#trackers': path.resolve(__dirname, '../Scripts/trackers')
},
},
entry: {
main: './main.js',
},
output: {
path: path.resolve(__dirname, '../Content/bundle'),
publicPath: '/Content/bundle/',
filename: '[name].bundle.js',
chunkFilename: process.env.NODE_ENV === 'production' ? '[id].js?v=[contenthash]' : '[name].js?v=[contenthash]'
},
plugins: [
new CleanWebpackPlugin(),
new webpack.ProgressPlugin(),
new webpack.DefinePlugin({
'process.env': {
'ENTRIES': JSON.stringify(entries),
'NODE_ENV': JSON.stringify(mode)
}
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[contenthash].[name].bundle.css',
}),
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: 'static'
})
],
module: {
rules: [
{
test: require.resolve('vue'),
use: [
{
loader: `expose-loader`,
options: 'Vue'
}
]
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(js)$/,
use: [
'babel-loader'
],
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[contenthash]'
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader',
'postcss-loader',
'sass-loader'
]
}
]
},
optimization: {
splitChunks: {
chunks: 'async'
}
},
performance: {
hints: false
},
externals: {
jquery: 'jQuery',
DM: 'DM'
},
stats: {
modules: false
},
target: 'web'
});
my BundleConfig:
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.IgnoreList.Clear();
BundleTable.EnableOptimizations = true;
bundles.Add(new ScriptBundle("~/bundles/js/head").Include(
"~/Scripts/head.js"
));
bundles.Add(new Bundle("~/bundles/js/scripts").Include(
"~/Content/bundle/main.bundle.js"
));
bundles.Add(new StyleBundle("~/bundles/css/main").Include(
"~/Content/bundle/*main.bundle.css"
));
bundles.Add(new StyleBundle("~/bundles/css/trends").Include(
"~/Content/bundle/*trends.bundle.css"
));
}
}
I've got webpack up and running and can't quite figure our how to get .scss file compiled to be used with custom styling such as colors etc. Bootstrap is otherwise loaded fine.
Here's my webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = (env = {}, argv = {}) => {
const isProd = argv.mode === 'production';
const config = {
mode: argv.mode || 'development', // we default to development when no 'mode' arg is passed
optimization: {
minimize: true
},
entry: {
main: './src/main.js'
},
output: {
filename: isProd ? 'bundle-[chunkHash].js' : '[name].js',
path: path.resolve(__dirname, '../wwwroot/dist'),
publicPath: "/dist/"
},
plugins: [
new MiniCssExtractPlugin({
filename: isProd ? 'style-[contenthash].css' : 'style.css'
}),
new CompressionPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$|\.eot?.+$|\.ttf?.+$|\.woff?.+$|\.svg?.+$/,
threshold: 10240,
minRatio: 0.8
}),
new HtmlWebpackPlugin({
template: '_LayoutTemplate.cshtml',
filename: '../../Views/Shared/_Layout.cshtml', //the output root here is /wwwroot/dist so we ../../
inject: false
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|jpg|gif|woff|woff2|eot|ttf|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[hash].[ext]',
outputPath: 'assets/'
}
}
]
}
};
return config;
};
I have node-sass installed which I think compiles it? Just not sure how to get it going.
Thanks,
You need to import your CSS into your entrypoint. So in main.js, import your scss file like this...
import './path-to/file.scss
As we are putting this output on a load balancer (not using sticky), we need to place the output of these files without chunks (neither hashes).
These are the main two files for webpack configuration.
webpack.common.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const helpers = require('./helpers');
const STATIC_TRANSLATION_MAP = require('../TranslationMap.json');
module.exports = {
entry: {
app: ['./src/public/main.ts'],
vendor: './src/public/vendor.ts',
polyfills: './src/public/polyfills.ts'
},
output: {
path: helpers.root('dist/public')
},
module: {
rules: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader', 'angular2-router-loader']
},
{
test: /\.html$/,
loader: 'html-loader?-minimize'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[ext]'
},
{
test: /\.styl$/,
include: helpers.root('src', 'public', 'app'),
use: [
'raw-loader',
'stylus-loader'
]
},
{
test: /\.styl$/,
include: helpers.root('src', 'public'),
exclude: helpers.root('src', 'public', 'app'),
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'stylus-loader'
]
})
},
{
test: /\.css$/,
include: helpers.root('src', 'public', 'assets', 'css'),
loader: 'raw-loader'
},
{
test: /\.xlf$/,
loader: 'raw-loader'
}
]
},
resolve: {
extensions: ['.webpack.js', '.web.js', '.ts', '.js'],
alias: {}
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/public/index.html'
}),
new webpack.DefinePlugin({
'process.env': {
'LOCALE_LIST': JSON.stringify(Object.keys(STATIC_TRANSLATION_MAP))
}
})
]
};
webpack.prod.js
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const commonConfig = require('./webpack.common.js');
const helpers = require('./helpers');
const prodEnv = 'production';
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
filename: '[name].js',
chunkFilename: '[name].js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({
mangle: {
keep_fnames: true
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false
}
}),
new ExtractTextPlugin('[name].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(prodEnv)
}
})
]
});
But for my surprise, I noticed webpack is producing extra files. Can you see those ones with numbers? (From 0 to 19). I'm not sure from where they're coming from, and every content of those starts with webpackJsonp.
Is there a way to disable this chunk feature and just produce the three files from entry?
What is happening?
But for my surprise, I noticed webpack is producing extra files. Can you see those ones with numbers? (From 0 to 19)
output.chunkFilename
This option determines the name of non-entry chunk files.
By default [id].js is used or a value inferred from output.filename (name is replaced with id):
Non-entry chunks (external)
./dist/[0].js
./dist/[1].js
./dist/[2].js
./dist/[3].js
...
Entry-chunks from webpack.config.entry
./dist/app.js
./dist/vendor.js
...
How to fix it?
Currently CommonChunkPlugin only receives modules imported from entry chunks.
webpack/issues/4392
Workarounds / hacks
This concept may be used to obtain implicit common vendor chunks:
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.indexOf("node_modules") !== -1;
}
})
Passing the minChunks property a function
webpack/issues/2855#issuecomment-239606760
https://stackoverflow.com/a/39401288/6836839
I am working on an Angular project and use Webpack bundler. Everything was working fine until Webpack started to ignore my changes to Typescript files. When I change a Typescript file, Webpack first says:
[WDS] App updated. Recompiling...
followed by:
[WDS] Nothing changed.
Also, killing webpack-dev-server and rebuilding the sources doesn't make any difference. The changes I make to TS files are not applied in any way.
EDIT: Loader setup on request (which is exactly the same as in the Angular Developer Guide):
webpack.common.js:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
module.exports = {
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts'
},
resolve: {
extensions: ['', '.js', '.ts']
},
module: {
loaders: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader']
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file?name=assets/[name].[hash].[ext]'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw'
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
webpack.dev.js:
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: helpers.root('dist'),
publicPath: 'http://localhost:8080/',
filename: '[name].js',
chunkFilename: '[id].chunk.js'
},
plugins: [
new ExtractTextPlugin('[name].css')
],
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
});
I set resolve.alias in webpack.config.js
alias: {
'$': 'jquery',
'_': 'underscore'
}
and require modules in my javascript file like this.
var $ = require('$');
var _ = require('_');
then there comes an error
Module not found: Error: Cannot resolve module '$'
I try to display error details and I find out that it still try to looking for modules named $ or _, not jquery or underscore.
So why doesn't the alias config work? Do I set a wrong config?
webpack.config.js
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var config = require('../config');
var projectRoot = path.resolve(__dirname, '../');
var buildPath = path.resolve(__dirname, 'demo');
module.exports = {
// eval-source-map is faster for development
devtool: '#eval-source-map',
entry: {
miceui: ['webpack-dev-server/client?http://localhost:3000',
'webpack/hot/dev-server',
path.resolve(projectRoot, 'index')]
},
output: {
path: buildPath,
filename: '[name].js'
},
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
new ExtractTextPlugin('[name].css'),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
})
],
module: {
loaders: [
{ test: /\.htm(l?)$/, loader: 'html-loader' },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader') },
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.(png|jpg|gif)$/, loader: 'url-loader?limit=8192' }
]
},
resolve: {
extensions: ['', '.js', '.jsx', '.coffee', '.html', '.css', '.scss'],
alias: {
'$': 'jquery',
'_': 'underscore'
}
}
};