Custom less-loader in Laravel Mix - javascript

I am trying to import LESS file in my JS code.
But I get error like - 'You may need an appropriate loader to handle this file type.'.
Version - "laravel-mix": "^0.11.4"
In my webpack.mix.js I tried this code
mix.webpackConfig({
module: {
rules: [{
test: /\.less$/,
loader: ['style-loader','css-loader','less-loader']
}]
}
})........
But I still getting the same error.

const path = require('path');
mix.webpackConfig({
module: {
rules: [
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
exclude: [
path.resolve(__dirname, "node-modules"),
path.resolve(__dirname, "resources/assets/less"),
],
},
]}
})
Works for my issue

Related

Webpack not building because CssSyntaxError

I am trying to run a webpack-dev-server built, but it fails everytime with the following error:
ERROR in ./src/style.css (./node_modules/css-loader/dist/cjs.js!./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./src/style.css)
Module build failed (from ./node_modules/css-loader/dist/cjs.js):
CssSyntaxError
(1:1) Unknown word
> 1 | var api = require("!../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js");
| ^
2 | var content = require("!!../node_modules/css-loader/dist/cjs.js!./style.css");
3 |
My webpack.dev.js looks like this:
const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
entry: './src/index.js',
mode: 'development',
devtool: 'inline-source-map',
optimization: {
usedExports: true,
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
],
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
],
},
});
The error appears on using this in my index.js:
import './style.css';
Many solutions suggest the order of the style-loader and the css-loader, but as far as I know it is in the correct order. What am I doing wrong?
I had the same error when trying to use the style-loader and the MiniCssExtractPlugin simultaneously. Your example uses webpack merge, so I assume that you also have a webpack.common.js somewhere with additional CSS rules?
In my case, what solved it was as following:
I have the following rules in my webpack.dev.config.js:
module: {
rules: [
{
test: /\.(sass|scss)$/,
use: [
"style-loader",
"css-loader",
"postcss-loader",
{
loader: "sass-loader",
options: {
// Prefer `dart-sass`
implementation: require("sass"),
},
},
],
},
],
},
And the following in my webpack.prod.config.js:
module: {
rules: [
{
test: /\.(sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
{
loader: "sass-loader",
options: {
// Prefer `dart-sass`
implementation: require("sass"),
},
},
],
},
],
},
You could also use the ternary operator to check if mode === 'production' and leave it in one file but I prefer to have two separate files to keep it more readable in case the webpack configs get too big.
I also tried to move the css-loader, postcss-loader and sass-loader to the same webpack.common.js file but for some reason it didn't work.
Not sure if that might be cause of your error but it fixed it in my use case so now I use the style loader for my dev environment and the plugin to compile for production.
This worked for webpack 5 and node 16

Add a specific node module in webpack bundle

I have added one of Bulma extensions in my react project
https://wikiki.github.io/components/quickview/
To use it I have installed it using npm & extension requires to add below line when DOM is completely loaded, so I added it in componentDidMount
var quickviews = bulmaQuickview.attach();
and below line in my index.html
<script type="text/javascript" src="/node_modules/bulma-extensions/bulma-quickview/dist/js/bulma-quickview.min.js"></script>
I am using webpack to bundle & have excluded all node modules from bundle.
Problem : In development environment for webpack it works fine but after bundling for production it gives me error that
bulmaQuickview is not defined
How can I bundle a specific node module in my webpack bundle? and what will be the correct reference to add.
Webpack config
module.exports = {
target: 'web',
entry: "./index.js",
output: {
filename: "bundle.js"
},
devtool: 'eval-source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.(png|jpg)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8000, // Convert images < 8kb to base64 strings
name: 'images/[hash]-[name].[ext]'
}
}]
},
{
test: /\.(png|svg|jpg|gif)$/,
include: path.join(__dirname, 'dist/image'),
loader: 'file-loader'
}
]
},
plugins: [new WebpackNotifierPlugin(), new BrowserSyncPlugin(), new ExtractTextPlugin("styles.css"),
new webpack.DefinePlugin({
'API_URL': API_URL[environment]
})
]
};
You're adding it to the index.html so webpack isn't bundling it. Have you tried importing it into the same js file that it is used in? Either that or add it to your entry property after index.html (make it an array).

Webpack: include specific file instead of package.json specified?

I have a webpack configuration:
var path = require("path");
module.exports = {
entry: {
app: [
'./src/index.js'
]
},
output: {
path: path.resolve(__dirname + '/dist'),
filename: '[name].js',
},
module: {
rules: [
{
test: /\.(css|scss)$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /\.js$/,
exclude: /node_modules/,
},
{
test: /\.html$/,
exclude: /node_modules/,
loader: 'file-loader?name=[name].[ext]',
},
{
test: /\.elm$/,
exclude: [/elm-stuff/, /node_modules/],
loader: 'elm-webpack-loader?verbose=true&warn=true',
options: {debug: true, warn: true},
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff',
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader',
},
],
noParse: /\.elm$/,
},
devServer: {
inline: true,
stats: { colors: true },
},
};
I have a few questions:
According to me the above config says that it should not be looking
for js files in node_modules. However it is still bundling
./node_modules/dexie/dist/dexie.es.js when I call require ("dexie"). (I am just doing this to experiment and understand webpack).
I would rather like to call dexie.js instead of dexie.es.js. How do
I make this happen. I know I can set the mainFields property.
However how do I do this on a prelibrary basis instead of globally.
Not sure if I understand your requirement fully, but an option is to set up aliases in the webpack resolve
module.exports = {
entry: {
...
},
output: {
...
},
module: {
rules: [
...
],
noParse: /\.elm$/,
},
resolve: {
alias: {
dixie: 'node_modules/dexie/dist/dexie.js'
}
},
devServer: {
...
},
};
To your first question please see here. It has already been answered.
No matter what you exclude in your loaders config, the file will be bundled unless you define it as external in your config.
To your second question, you can just require the other file with
require('dexie/dexie.js')
When you just write require('dexie'), webpack will look in your node_modules folder for a folder named 'dexie', read the package.json and resolve the file described by the module property. This is described here.
For more info, please read the webpack docs. They are excellent.

Webpack configuration not loading my image paths on .ts files

I'm very new with webpack, and actually this whole modern front-end development. I'm trying to learn angular2 this past few weeks, it was fine until I wanted to deploy it. I came across webpack that produces the index.html with all the angular2 thingy packed on a script, so I could deploy the website I am experimenting.
The problem is when the paths of my images doesn't seem to be processed by webpack. Html and css were fine, but when I try do something like:
import {ImageSection} from './image-section';
export const PAGEONE: ImageSection = {
title: "Page One",
imgsrc: "../../../public/images/pageone.png"
}
Here's my webpack configuration:
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: ['', '.ts', '.js']
},
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'
})
]
};
Should I add some loader on the .ts one? I'm just really trying to learn angular, forgive my noobness on webpack. I just really want to make it work, study angular first to at least a comfortable degree and then start learning this webpack thing.
webpack cannot guess from arbitrary JavaScript strings, whether the string needs to be loaded. You need to require the resource. In your example, replace
imgsrc: "../../../public/images/pageone.png"
with
imgsrc: require("../../../public/images/pageone.png")
This emits pageone.png as file in the output directory and returns the public URL. For details see the usage section of the file-loader.

Webpack: Loading images from html templates

I'm trying to set up an angular project using Webpack but I can't figure out how to reference images from within html templates and have them included in the build.
My project tree is as follows:
package.json
app/
- images/
- foo.png
- scripts/
- styles/
- templates/
I'm trying to use html-loader along with url-loader and file-loader but it's just not happening.
This is an example template: app/templates/foo.html
<img src="../images/foo.png" />
Problem #1: I would like to be able to reference images relative to app/. Right now, the paths need to be relative to the template file and this will get ugly very quickly (../../../images/foo.png).
Problem #2: Even if I specify the relative path, as I have done above, the project builds successfully but nothing really happens. The paths are left as-is and no images appear in dist/.
Here is my webpack config:
var path = require('path');
var webpack = require('webpack');
var ngminPlugin = require('ngmin-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ngAnnotatePlugin = require('ng-annotate-webpack-plugin');
module.exports = function(config, env) {
var appRoot = path.join(__dirname, 'app/')
if(!env) env = 'development';
var webpackConfig = {
cache: true,
debug: true,
contentBase: appRoot,
entry: {
app: path.join(appRoot, '/scripts/app.coffee')
},
output: {
path: path.join(__dirname, 'dist/),
publicPath: '/',
libraryTarget: 'var',
filename: 'scripts/[name].[hash].js',
chunkFilename: '[name].[chunkhash].js'
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader?outputStyle=expanded&includePaths[]=./node_modules/foundation/scss/')
},
{
test: /\.coffee$/,
loader: 'coffee-loader'
},
{
loader: 'ngtemplate?relativeTo=' + (path.resolve(__dirname, './app')) + '/!html'
},
{
test: /\.png$/, loader: "url-loader?limit=100000&mimetype=image/png&name=[path][name].[hash].[ext]"
},
{
test: /\.jpg$/, loader: "file-loader?name=[path][name].[hash].[ext]"
},
{
test: /\.(woff|woff2)(\?(.*))?$/,
loader: 'url?prefix=factorynts/&limit=5000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.eot(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.svg(\?(.*))?$/,
loader: 'file?prefix=fonts/'
},
{
test: /\.json$/,
loader: 'json'
}
]
},
resolve: {
extensions: [
'',
'.js',
'.coffee',
'.scss',
'.css'
],
root: [appRoot],
},
singleRun: true,
plugins: [
new webpack.ContextReplacementPlugin(/.*$/, /a^/),
new webpack.ProvidePlugin({
'_': 'lodash'
}),
new ExtractTextPlugin("styles/[name].[chunkhash].css", {allChunks: true}),
new HtmlWebpackPlugin({
template: appRoot + '/app.html',
filename: 'app.html',
inject: 'body',
chunks: ['app']
})
],
devtool: 'eval'
}
if(env === 'production') {
webpackConfig.plugins = webpackConfig.plugins.concat(
new ngAnnotatePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.DefinePlugin({
'process-env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
);
webpackConfig.devtool = false;
webpackConfig.debug = false;
}
return webpackConfig;
}
If you are using HTML templates in Webpack 2, in addition to use the file-loader you need to change in your HTML:
<img src="../images/foo.png" />
to this
<img src=<%=require("../images/foo.png")%> />
Yes, you will have to do so for loading images from different path.
I had similar issue and I resolved this using file loader:
.
loaders: [{
// JS LOADER
test: /\.js$/,
loader: 'babel-loader?optional[]=runtime',
exclude: /node_modules/
}, {
// ASSET LOADER
test: /\.(woff|woff2|ttf|eot)$/,
loader: 'file-loader'
},
{
//IMAGE LOADER
test: /\.(jpe?g|png|gif|svg)$/i,
loader:'file-loader'
},
{
// HTML LOADER
test: /\.html$/,
loader: 'html-loader'
},
{
//SCSS LOADER
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader?indentedSyntax"]
}
]
Good Luck
For Webpack 5 you have to write this way:
module: {
rules: [
// other stuff above.....
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
}
]
}
With Webpack 4, I was able to solve this problem by updating by html-loader to specify the root for my files. So given #syko's original structure; in webpack.config.js...
module: {
rules: [
// other stuff above.....
{
test: /\.html$/,
use: [
// ...The other file-loader and extract-loader go here.
{
loader: 'html-loader'
options: {
// THIS will resolve relative URLs to reference from the app/ directory
root: path.resolve(__dirname, 'app')
}
}
]
}
]
}
This tells the html-loader to interpret all absolute urls from the /app folder. So in our app/templates/foo.html, you can then use the following...
<img src="/images/foo.png" />
This then tells html-loader to see the above as path.resolve(__dirname, 'app', 'images', 'foo.png'). Then if you have extract-loader and/or file-loader, all the paths should be correct.
Managed to get this solution after hammering away at it for a while. The biggest confusion is where about in the loader stack the /images/foo.png is interpreted, in this case it starts at the html-loader plugin. Everything else after that, is more about how the image files are to be published.
Hope that helps.
You can use file-loader to extract images. Then using html-loader you can specify which tag-attribute combination should be processed by this loader via the query parameter attrs.
I could make it work with this configuration:
{
test: /\.(jpe?g|png|gif|svg|ico)$/i,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}]
},
{
test: /\.(html)$/,
use: {
loader: 'html-loader',
options: {
attrs: ['img:src', 'link:href']
}
}
}
Or in angular something like this:
attrs: [':ng-src', ':ng-href']

Categories

Resources