My relevant portion of my project directory looks like this:
root
--src
--js
--styles
--less
--main.less
--fonts
--Pixelated.tff
--webpack.config.js
This is the relevant portion of my webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
'webpack-hot-middleware/client',
'./src/js'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: [ 'babel' ],
exclude: /node_modules/,
include: __dirname
}, {
test: /\.less?$/,
loaders: [ 'style', 'css', 'less' ],
include: __dirname
},
{test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }]
}
};
In main.less, this is the relevant #font-face portion:
#font-face {
font-family: 'Pixelated';
src: url('../fonts/Pixelated.ttf');
}
I've tried a couple of variations on the webpack loader with various github issues I've looked over to no avail. I've also tried using the absolute path to my tff font file just for proof of concept and that isn't working either, which I imagine must be related to my webpack setup.
Change your
{
test: /\.less?$/,
loaders: [ 'style', 'css', 'less' ],
include: __dirname
},
to
{
test: /(\.less|\.css)$/,
loaders: [ 'style', 'css', 'less' ],
}
It should work, the main.css file is a css and you need to use an appropriate loader for that type of files.
Related
I am currently switching a web app to have its assets bundled using Webpack. Bundling JS and CSS was somewhat straightforward. Then came the turn of images. My question is how one can approach bundling images.
In particular, suppose I have static_src from which everything originates and static_compiled into which the bundled output is placed. I would like the image contents of static_src/img to move into static_compiled/img. How does one accomplish this?
On another note, is this a sensible approach or am I misunderstanding some philosophy behind Webpack and misusing it?
Current config is roughly like this:
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: { index: path.resolve(__dirname, "static_src", "index.js") },
output: {
path: path.resolve(__dirname, "static_compiled"),
publicPath: "/static/", // Should match Django STATIC_URL
filename: "[name].js", // No filename hashing, Django takes care of this
chunkFilename: "[id]-[chunkhash].js", // DO have Webpack hash chunk filename, see below
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
],
module: {
rules: [
{
test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'}, // to transform JSX into JS
{
test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"]},
{
test: /\.css$/, use: ["style-loader", "css-loader"]},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader'},
{
test: /\.svg$/,
loader: 'svg-inline-loader'},
/* {
test: /\.(ico|png|jpg|gif)$/,
loader: 'file-loader'} */
{
test: /\.(ico|png|svg|jpg|gif|jpe?g)$/,
use: [
{
options: {
name: "[name].[ext]",
outputPath: "img/"
},
loader: "file-loader"
}
]
}
],
},
resolve: {
alias: {
shared: path.resolve(__dirname, 'node_modules', 'bower_components')
},
extensions: ['.js', '.ts', 'jsx', 'tsx']
},
devServer: {
writeToDisk: true, // Write files to disk in dev mode, so Django can serve the assets
}
}
The code I ended up using looks something like this.
plugins section:
plugins: [...
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, `static_src/img`),
to: 'img',
}
]
}),
module-rules section:
module: {
rules: [
{ ...
test: /\.(ico|png|jpg|gif|jpe?g)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "img/"
}
}
]
}
I just installed react, webpack, and babel into one of my projects (I used this tutorial https://medium.com/swlh/a-complete-webpack-setup-for-react-e56a2edf78ae but I tweaked a bit of the webpack.config.js file because it was giving errors) and now my css stylesheet for my html file doesn't link (when I type npm run start) and I'm not exactly sure why
This is how I link my stylesheet
<link rel="stylesheet" type="text/css" media="screen" href="index-styles.css">
This is my webpack.config.js
const path = require("path");
const autoprefixer = require("autoprefixer");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
chunkFilename: "[id].js",
publicPath: ""
},
resolve: {
extensions: [".js", ".jsx"]
},
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: "style-loader" },
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]"
},
sourceMap: true
}
},
{
loader: "postcss-loader"
// postcssOptions: {
// ident: "postcss",
// options: {
// }
// //plugins: () => [autoprefixer({})]
// }
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: "url-loader?limit=10000&name=img/[name].[ext]"
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + "/src/index.html",
filename: "index.html",
inject: "body"
})
]
};
And right now my project structure is
assets
images
node_modules
src
|___index-styles.css (one I'm linking to index.html)
|___index.css (one used in index.js for tutorial)
|___index.html
|___index.js
.babelrc
package-lock.json
package.json
webpack.config.js
I'm very new to Webpack and I'm not certain how to handle LESS. I want to have many LESS files and I want them to compile into one CSS file after I run npm run build. This would result in a style.css file which includes everything.
My webpack.config.js looks like this:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules:
[
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.less$/,
use: [{
loader: "style-loader", // creates style nodes from JS strings
path: path.resolve(__dirname, 'src')
}, {
loader: "css-loader", // translates CSS into CommonJS
path: path.resolve(__dirname, 'src')
}]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.json$/,
loader: 'json-loader'
}
]
},
plugins: [new HtmlWebpackPlugin()]
};
How exactly do I configure webpack to make it combine all LESS files into one CSS file?
You can use a plugin called extract-text-webpack-plugin to achieve this. According to their documentation, this plugin moves all the required *.css modules in entry chunks into a separate CSS file. So your styles are no longer inlined into the JS bundle, but in a separate CSS file (styles.css). Now of course, in your case, you will first have to parse your .less files to .css and then bundle them up into a single file.
You can modify your webpack config like so:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({ <---- Use the plugin here to extract the styles
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
},
{
test: /\.json$/,
loader: 'json-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin(),
new ExtractTextPlugin("styles.css"),
]};
You can use extract-text-webpack-plugin to make one css file. But only do this for a production build not while you are developing.
I would look at using the Webpack less-loader. It covers a production build here
i am using mern.io my web pack config is looks like :
var webpack = require('webpack');
var cssnext = require('postcss-cssnext');
var postcssFocus = require('postcss-focus');
var postcssReporter = require('postcss-reporter');
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: {
app: [
'eventsource-polyfill',
'webpack-hot-middleware/client',
'webpack/hot/only-dev-server',
'react-hot-loader/patch',
'./client/index.js',
],
vendor: [
'react',
'react-dom',
],
},
output: {
path: __dirname,
filename: 'app.js',
publicPath: 'http://0.0.0.0:8888/',
},
resolve: {
extensions: ['', '.js', '.jsx'],
modules: [
'client',
'node_modules',
],
},
module: {
loaders: [
{
test: /\.css$/,
exclude: /node_modules/,
loader: 'style-loader!css-loader?localIdentName=[name]__[local]__[hash:base64:5]&modules&importLoaders=1&sourceMap!postcss-loader',
}
, {
test: /\.css$/,
include: /node_modules/ ,
loaders: ['style-loader', 'css-loader'],
}
, {
test: /\.jsx*$/,
exclude: [/node_modules/, /.+\.config.js/],
loader: 'babel',
}, {
test: /\.(jpe?g|gif|png|svg)$/i,
loader: 'url-loader?limit=10000',
}, {
test: /\.json$/,
loader: 'json-loader',
},
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=1&minetype=application/font-woff" },
{ test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=1&minetype=application/font-woff" },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=1' }
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor.js',
}),
new webpack.DefinePlugin({
'process.env': {
CLIENT: JSON.stringify(true),
'NODE_ENV': JSON.stringify('development'),
}
}),
],
postcss: () => [
postcssFocus(),
cssnext({
browsers: ['last 2 versions', 'IE > 10'],
}),
postcssReporter({
clearMessages: true,
}),
],
};
i would like to add a custom css file which resides in : /public/assets/css/custom.css; Then what would be my configurations?
i can import css file in node_modules eg : require('rc-slider/assets/index.css');
as it says in the config :
{
test: /\.css$/,
include: /node_modules/ ,
loaders: ['style-loader', 'css-loader'],
}
i have replicated the entry with :
{
test: /\.css$/,
include: /public/ ,
loaders: ['style-loader', 'css-loader'],
}
but not working
There can be two approach to handle this situation.
1.
You can use the following to add public folder to serve static files.
app.use(express.static('public'));
And then you can add the file in the html if you are using server side rendering.
2.
You can put this file on client side and simply import the file at the entry point of webpack on client side.
And webpack will automatically include it using style loader.
I started new project with react-hot-boilerplate. Everything worked fine until i tried to add a css file to index.html.
<Link href="/style/main.css" rel="stylesheet">
Hot-loader doesnt read the css file. After some research i found out this line in server.js redirect all request to index.html
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
i changed it to
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'index.html'));
});
app.get('/style/main.css', function(req, res) {
res.sendFile(path.join(__dirname, 'style/main.css'));
});
and it worked. is there any better way to do that? do i need to map all the resources i servere.js?
I dont want to use style-loader or css-loader in webpack because i get a lot of errors and i cant simply use className="myCustomStyle".
var path = require('path');
var webpack = require('webpack');
var packageJSON = require('./package.json');
const PATHS = {
build: path.join(__dirname, 'target', 'classes', 'META-INF', 'resources', 'webjars', packageJSON.name, packageJSON.version)
};
module.exports = {
devtool: 'cheap-module-source-map',
resolve: {
extensions: ['', '.js', '.jsx', '.scss'],
alias: {
config: path.join(__dirname, 'src/config/dev.js'),
},
},
entry: [
'webpack-hot-middleware/client',
'./src/index'
],
output: {
path: PATHS.build,
filename: 'app-bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, 'src')
}, {
test: /\.css$/,
loader: 'style-loader!css-loader?modules=true&localIdentName=[name]__[local]___[hash:base64:5]'
}]
}
};
Loading the static files should not be handled on server side. So you should not insert your styling or js files in server else the loading time would be more and since you are using react so all your files would be js so if you write the resource to be sent on the server then it's of no use. so the best option is to write loaders in webpack.
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
exclude: /(node_modules|bower_components)/
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(png|jpg)$/,
loader: 'file-loader'
}
]
}
If you want to do something like
<div className={styles.app}>
Then your component should be like
export default class Mycomponent extends Component{
let styles = {
app:{
'color': 'red',
}
}
return(){
render(
<div className={styles.app}>
)
}
}
This will solve your problem