Webpack cannot find properly path for slick files - javascript

I started to using a webpack bundler, and I got a little issue with slick slider.
Slick fonts and gif doesn't load properly
It looks like webpack skips main folder, where my project is, and looking for files in d:/node_modules instead of d:/main_folder/node_modules
I was trying to fix this by creating slick-fix.scss and set font and loader path
but it doesn't work properly
This is the error screenshot:
slick-fix.scss
$slick-loader-path: "/node_modules/slick-carousel/slick/" !default;
$slick-font-path: "/node_modules/slick-carousel/slick/fonts/" !default;
main.scss
#import "slick-fix";
#import "~slick-carousel/slick/slick.scss";
#import "~slick-carousel/slick/slick-theme.scss";
main.js
require('./styles/main.scss');
require('jquery');
import 'slick-carousel/slick/slick';
$('.slider').slick();
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const webpack = require('webpack');
const $ = require('jquery');
module.exports = {
context: path.resolve(__dirname),
entry: './src',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['#babel/preset-env']
}
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
]
},
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
}
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.$': 'jquery',
'window.jQuery': 'jquery'
})
]
}

You cannot access local paths from your http server. In other words, you cannot load files from your harddrive directly. They have to be served by the server.

Related

How to avoid loading from chunk in webpack? [Angular] [inline js]

I am trying to bundle a angular project into a single file (js, css and html). I've managed to get the html and css working and js is also inline now (using HtmlWebpackInlineSourcePlugin). The js files generated after minification are like below:
The vendor, main and polyfill are inline in the index.html. But I see that the generated js for main and vendor js are trying to load from the chunk 3.js (this has the actual js that's written for the app).
I want this chunk also to be inline, but can't seem to find a way to do it. Even if I did manage to make it inline, how do I avoid vendor/main js from loading this chunk. The webpack config is below.
'use strict';
const webpackMerge = require('webpack-merge');
const ngw = require('#ngtools/webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
const isDev = process.env.NODE_ENV !== 'production';
//just a wrapper for path
const helpers = require('./helpers');
module.exports = {
mode: 'production',
output: {
path: helpers.root('dist'),
filename: '[name].js',
},
resolveLoader: {
modules: [helpers.root('node_modules')]
},
entry: {
vendor: './src/vendor.ts',
polyfills: './src/polyfills.ts',
main: './src/main.ts'
},
resolve: {
extensions: ['.ts', '.js', '.scss']
},
module: {
rules: [
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(scss|sass)$/,
use: [
{ loader: 'style-loader', options: { sourceMap: isDev } },
{ loader: 'css-loader', options: { sourceMap: isDev } },
{ loader: 'sass-loader', options: { sourceMap: isDev } }
],
include: helpers.root('src', 'assets')
},
{
test: /\.(scss|sass)$/,
use: [
'to-string-loader',
{ loader: 'css-loader', options: { sourceMap: isDev } },
{ loader: 'sass-loader', options: { sourceMap: isDev } }
],
include: helpers.root('src', 'app')
},
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
loader: '#ngtools/webpack'
}
]
},
plugins: [
new ngw.AngularCompilerPlugin({
tsConfigPath: helpers.root('tsconfig.json'),
entryModule: helpers.root('src', 'app', 'app.module#AppModule')
}),
new HtmlWebpackPlugin({
template: 'src/index.html',
inlineSource: '.(js|css)$',
}),
new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin),
// new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/chunk/])
]
};
FYI - I want it to be a single inline file because I need to use in google apps script (editor add on).
I ended up solving this using libraryTarget in webpack to compile to umd.
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].js',
libraryTarget: "umd",
globalObject: 'this'
}

Unable to load styles using MiniCssExtractPlugin in Webpack 4 for Wordpress

I'm using Webpack 4 for Wordpress theme development. I have configured my webpack.config.js to extract css from js files and load them in separate files. But the styles are not getting loaded, either as or as separate css file.
webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
context: __dirname,
entry: {
userSide: "./js/public.js",
adminSide: "./js/admin.js"
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
mode: "development",
devtool: "source-map",
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/,
use: [
{
loader: "file-loader",
options: {
outputPath: "dist/images",
name: "[name].[ext]"
}
}
]
},
{
test: /\.s?css$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css"
})
]
};
The css files are being created in the local directory whenever I run npm run dev but not showing changes in the website.
Please help
This is how I config my webpack
You can use my setting to see if it work for you
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
Add to plugins section:
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
}),
And rules section
{
"test":"/\\.scss$/",
"use":[
"style-loader",
"MiniCssExtractPlugin.loader",
{
"loader":"css-loader",
"options":{
"minimize":true,
"sourceMap":true
}
},
{
"loader":"sass-loader"
}
]
},
Also you may need to inject css to your html using HTML Webpack plugin

webpack 4 gives background: url([object Module]) as bg image

I'm having issues with setting up web-pack 4 and svg-sprite-loader to render svg icons as background images. I was following these instructions from official docs for svg-sprite-loader (https://github.com/kisenka/svg-sprite-loader/tree/master/examples/extract-mode).
I have successfully managed to create sprite.svg file in my dist folder and use it as reference for my use tags inside of html. However, i was also trying to use svg icons from my src/images/icons folder for a background image like this:
background: url('../images/icons/upload_icon.svg') 10% 50% no-repeat;
when doing this, webpack compiles correctly, but creates this in dist css file:
background: url([object Module]) 10% 50% no-repeat;
Any help would be great.
here is my webpack config file:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
module.exports = {
mode: "development",
devtool: "source-map",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
sourceMap: true
}
}
},
{
// scss configuration
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader"
},
{
loader: "postcss-loader"
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
}
]
},
{
// html configuration
test: /\.html$/,
use: {
loader: "html-loader"
}
},
{
// images configuration
test: /\.(jpg|jpeg|gif|png|woff|woff2)$/,
use: [
{
loader: "file-loader",
options: {
name: "[path][name].[ext]"
}
}
]
},
{
test: /\.svg$/,
use: [
{
loader: "svg-sprite-loader",
options: {
extract: true,
spriteFilename: "sprite.svg"
}
}
]
}
]
},
plugins: [
// all plugins used for compiling by webpack
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "Style Guide",
template: path.resolve(__dirname, "src", "index.html")
}),
new MiniCssExtractPlugin({
filename: "app.css"
}),
new SpriteLoaderPlugin()
]
};
Adding esModule: false to the file-loader options did the trick for me.
{
test: /\.(jpg|png|gif|svg)$/,
use: {
loader: 'file-loader',
options: {
name: "[name].[ext]",
outputPath: "img",
esModule: false
}
},
You have to pass esModule: false for svg-sprite-loader options.
By the way (it is not related to esModule): With MiniCssExtractPlugin you can not to extract svg sprite. I've faced this problem one hour ago..
After a few hours, I have managed to make this thing to work, thanks to #WimmDeveloper for pointing me in right direction. Main change from prior webpack config file is that I have added esModule: false in svg-sprite-loader options and replaced MiniCssExtractPlugin with extract-text-webpack-plugin. Mind you that this solution is not ideal since this webpack plugin is deprecated.
here is my full webpack config file:
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
mode: "development",
devtool: "source-map",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
sourceMap: true
}
}
},
{
test: /\.(s*)css$/,
use: ExtractTextPlugin.extract({
use: ["css-loader", "postcss-loader", "sass-loader"]
})
},
{
// html configuration
test: /\.html$/,
use: {
loader: "html-loader"
}
},
{
test: /\.svg$/,
use: [
{
loader: "svg-sprite-loader",
options: {
esModule: false,
extract: true,
spriteFilename: "sprite.svg"
}
}
]
},
{
// files configuration
test: /\.(jpg|jpeg|gif|png|woff|woff2)$/,
use: [
{
loader: "file-loader",
options: {
name: "[path][name].[ext]"
}
}
]
}
]
},
plugins: [
// all plugins used for compiling by webpack
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "Style Guide",
template: path.resolve(__dirname, "src", "index.html")
}),
new ExtractTextPlugin({ filename: "app.css" }),
new SpriteLoaderPlugin()
]
};

Webpack vendor 3rd party modules and babel-loader

My webpack build has 2 entries the vendor.js => vendor.js file and index.js => bundle.js.
Obviously vendor.js is the file where all the 3rd party libraries go, and in index.js goes my code.
I've been encountering some issues, many of the 3rd party libraries I include (in vendor.js), does not execute from bundle.js . Why is that?
My webpack configuration:
import path from 'path';
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var CopyWebpackPlugin = require('copy-webpack-plugin');
var precss = require('precss');
var autoprefixer = require('autoprefixer');
module.exports = {
entry: {
bundle: './dev/index.js',
vendor: './dev/vendor.js'
},
output: {
path: path.join(__dirname, 'dist'),
// publicPath: 'http://localhost:3000/',
filename: '[name].[hash].js',
chunkFilename: '[id].bundle.js'
},
externals: [
{
"./dev/assets/Paraxify/paraxify.js": "paraxify",
}
],
module: {
loaders: [
{
test: /\.js$/,
// exclude: path.resolve(__dirname, "node_modules"),
loader: 'babel-loader',
// exclude: [
// path.resolve(__dirname, "node_modules"),
// ],
query: {
compact: true,
plugins: ["transform-es2015-modules-commonjs"],
presets: ['es2015', 'stage-0']
}
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract(
"style",
"css!postcss-loader!sass")
},
// { test: /jquery/, loader: 'expose?$!expose?jQuery' },
{ test: /\.jpg$/, loader: "file-loader?name=./assets/imgs/[name].jpg" },
{ test: /\.png$/, loader: "file-loader?name=./assets/imgs/[name].png" },
{ test: /\.(gif|woff|woff2|eot|ttf|svg)$/, loader: "url-loader" },
// { test: /\grabbing.gif$/, loader: "url-loader" },
// { test: /\preloader.gif$/, loader: "url-loader" },
// { test: /\default-skin.svg$/, loader: "url-loader" },
// { test: /\/default-skin.png$/, loader: "url-loader" }
// { test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }
]
},
postcss: function () {
return [precss, autoprefixer];
},
plugins: [
new CopyWebpackPlugin([
{ from: './dev/assets', to: 'assets' }
]),
new CopyWebpackPlugin([
{ from: './dev/bootstrap3', to: 'bootstrap3' }
]),
new webpack.optimize.CommonsChunkPlugin({
name: ['bundle', 'vendor']
}),
new HtmlWebpackPlugin({
hash: false,
template: 'ejs!./dev/index.html',
inject: 'body'
}),
new ExtractTextPlugin("styles.[hash].css"),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
// new webpack.ProvidePlugin({
// twentytwenty: "frontend/dev/assets/twentytwenty/js/jquery.twentytwenty"
// })
]
};
Example of the issue :
Vendor.js : Importing Scrollreveal (https://scrollrevealjs.org/)
import $ from 'jquery';
// import 'eqcss';
// import Rx from 'rx';
import * as ScrollReveal from 'scrollreveal';
And when I do : window.sr = ScrollReveal({ reset: true }); for the variable to be available globally, I get an error in the browser's console : Uncaught TypeError: ScrollReveal is not a function
Can someone explain me What I'm doing incorrectly? Thanks

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