I have a directory structure like this:
and inside node_modules:
>node_modules >./bin >webpack.config.js >bootstrap >bootstrap.css >bootstrap.js
I need to generate separate CSS and JS bundles like this:
custom-styles.css, custom-js.js, style-libs.css, js-libs.js
where style-libs
and js-libs
should contain syles and js files of all libraries like bootstrap and jQuery. Here's what I have done so far:
webpack.config.js:
const path = require('path'); const basedir = path.join(__dirname, '../../client'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const stylesPath = path.join(__dirname, '../bootstrap/dist/css'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { watch: true, // Script to bundle using webpack entry: path.join(basedir, 'src', 'Client.js'), // Output directory and bundled file output: { path: path.join(basedir, 'dist'), filename: 'app.js' }, // Configure module loaders (for JS ES6, JSX, etc.) module: { // Babel loader for JS(X) files, presets configured in .babelrc loaders: [ { test: /\.jsx?$/, loader: 'babel', babelrc: false, query: { presets: ["es2015", "stage-0", "react"], cacheDirectory: true // TODO: only on development } }, { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }, ] }, // Set plugins (for index.html, optimizations, etc.) plugins: [ // Generate index.html new HtmlWebpackPlugin({ template: path.join(basedir, 'src', 'index.html'), filename: 'index.html' }), new ExtractTextPlugin(stylesPath + "/bootstrap.css", { allChunks: true, }) ] };
Client.js
import * as p from 'babel-polyfill'; import React from 'react'; import ReactDOM from 'react-dom'; import App from './components/App.jsx'; ReactDOM.render(<App />, document.getElementById('app'));
I am able to run the app and render all of the components correctly except loading the external JS and CSS file using webpack
.
I'm not much experienced with webpack and find it really difficult it wrap my hear around it. There're are a few simple questions:
1- Is this configuration correct? If yes, then how can I include my CSS and JS files in components using ES6. Something like import
keyword.
2- Should I even be using webpack for CSS files?
3- How to specify individual directories for input and their respective output files in webpack? Something like all-custom.js
should be output for custom1.js
and custom2.js
?
I know these are some very basic question and I tried Google but didn't find a single tutorial for Webpack that is simple and targets beginners.
- You can include css & JS files using import in es6 in the source files in your project. example:
import './style.css';
import Style from './path/style.js';
NB. Generally You need to code in es5 in webpack.config.js file. If you want to use es6 just follow the link How can I use ES6 in webpack.config.js?
You can use https://github.com/webpack/css-loader for CSS configuration.
You can use code splitting in webpack and specify multiple entry point but that will generate multiple output files. Have a look at multiple entry point section of that following link. https://webpack.github.io/docs/code-splitting.html
After playing out with Webpack in multiple projects, I figured out how Webpack loads stuff. Since the question is still unanswered, I decided to do it myself for anybody with same need.
Directory structure
->assets ->css ->my-style-1.css //custom styling file 1 ->my-style-2.css //custom styling file 2 ->src ->app ->app.js ->variables.js ->libs.js //require all js libraries here ->styles-custom.js //require all custom css files here ->styles-libs.js //require all style libraries here ->node_modules ->index.html ->package.json ->webpack.config.js
Bundle 1 (main code of app)
app.js
: assuming this is main file and app starts from here
var msgs = require('./variables'); //similarly import other js files you need in this bundle //your application code here... document.getElementById('heading').innerText = msgs.foo; document.getElementById('sub-heading').innerText = msgs.bar;
Bundle 2 (js modules)
libs.js
: this file will require all modules needed
require('bootstrap'); //similarly import other js libraries you need in this bundle
Bundle 3 (external css files)
styles-libs.js
: this file will require all external css files
require('bootstrap/dist/css/bootstrap.css'); //similarly import other css libraries you need in this bundle
Bundle 4 (custom css files)
styles-custom.js
: this file will require all custom css files
require('../assets/css/my-style-1.css'); require('../assets/css/my-style-2.css'); //similarly import other css files you need in this bundle
webpack.config.js
const path = require('path'); const webpack = require('webpack'); const extractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: { 'app': './src/app/app.js', //specifying bundle with custom js files 'libs': './src/libs.js', //specifying bundle with js libraries 'styles-custom': './src/styles-custom.js', //specifying bundle with custom css files 'styles-libs': './src/styles-libs.js', //specifying bundle with css libraries }, module: { loaders: [ //used for loading css files { test: /\.css$/, loader: extractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader?sourceMap' }) }, //used for loading fonts and images { test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, loader: 'file-loader?name=assets/[name].[hash].[ext]' } ] }, output: { path: path.resolve(__dirname, 'dist'), //directory for output files filename: '[name].js' //using [name] will create a bundle with same file name as source }, plugins: [ new extractTextPlugin('[name].css'), //is used for generating css file bundles //use this for adding jquery new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jQuery' }) ] }
index.html
<head> <link rel="stylesheet" href="dist/styles-libs.css" /> <link rel="stylesheet" href="dist/styles-custom.css" /> </head> <body> <h2 id="heading"></h2> <h3> <label id="sub-heading" class="label label-info"></label> </h3> <script src="dist/libs.js"></script> <script src="dist/app.js"></script> </body>