Use webpack with jade-loader without explicitly requiring assets - javascript

I am trying to use Webpack jade-loader in combination with html-loader to be able to omit requires in jade templates + use a path relative to a certain folder. I have tried a few things, none of them worked.
By default jade-loader works when using img(src=require("../../../../assets/images/imac.png") alt="computer"), with the following webpack config:
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./app/app.js'
],
context: path.resolve(__dirname + "/client"),
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
// placed here so we know that it is done before transpiling
preLoaders: [
{ test: /\.js$/, loader: "eslint-loader", exclude: [/node_modules/, /\.config\.js/, /\.conf\.js/ ] }
],
loaders: [
{ test: /\.html$/, loader: 'raw' },
{ test: /\.jade$/, loader: 'jade-loader' },
{ test: /\.less$/, loader: 'style!css!less' },
{ test: /\.css/, loader: 'style!css' },
{ test: /\.(png|jpg|jpeg|svg)$/, loader: 'file' },
{ test: /\.js$/, loader: 'babel?stage=1', exclude: [/client\/lib/, /node_modules/, /\.spec\.js/] }
]
},
eslint: {
configFile: './.eslintrc'
}
};
If I add the html-loader ({ test: /\.jade$/, loader: 'html-loader!jade-loader' }) which is supposed to require sources by default, I keep getting the 'Error: Module not found'. The console logs all the paths that it tried, all relative to the current working file.
I tried to give it some context, with context: path.resolve(__dirname + "/client"). It didn't work either.
I also tried to combine with the raw loader: raw-loader!html-loader!jade-loader. I don't get the error but the wepback output that is served is not my app at all, but instead something along the lines of:
var jade = require(/......) ....
Do you have any idea ?
Thanks for your help

Had the same Problem.
https://www.npmjs.com/package/pug-html-loader worked for me:
module.exports = {
// your config settings ...
module: [
//your modules...
loaders: [{
include: /\.jade/,
loader: 'pug-html-loader'
}]
]
};

I don't know what do you want. My need is to load a template from a directive (component in 1.5)
angular.module('app').component('myComponent', {
bindings: {},
template: require('./mytemplate.jade')()
});
You can to note that I'm invoking the returned function.

Related

react production build, assets not loading

I am experiencing annoying problem, when i run my react app in development environment it all works ok, but when i try to build to production, all the links are wrong.
assume this tree:
main_directory
public/
svg/
some_img.svg
src/
components/
some_component.jsx
App.js
index.js
Now in some_component.jsx i am referencing svg file in this way:
src="/public/svg/some_img.svg"
however after building to production this path is untouched and therefore cannot access file anymore, as there i would need it to be changed to this:
src="svg/some_img.svg"
i was playing in the webpack config file, i thought that maybe by setting:
publicPath: "/"
to:
publicPath: "/public/"
would resolve the problem but the only thing it did was error during application start:
CANNOT GET/
my webpack config:
const HtmlWebPackPlugin = require("html-webpack-plugin");
const htmlPlugin = new HtmlWebPackPlugin({
template: "./public/index.html",
filename: "./index.html"
});
module.exports = {
output: {
filename: "main.[hash:8].js",
publicPath: "/"
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /node_modules/,
loader: "babel-loader?presets[]=react"
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(sass|scss)$/,
use: ["style-loader", "css-loader", "sass-loader", "postcss-loader"]
},
{
test: /\.svg$/,
loader: "svg-sprite-loader"
}
]
},
plugins: [htmlPlugin],
devServer: {
historyApiFallback: {
rewrites: [{ from: /^\/$/, to: "/index.html" }]
}
},
resolve: {
extensions: [".js", ".jsx", ".json"]
}
};
How does one resolve this problem, so for both dev and production paths are unified?
How about importing the svg and then referencing the imported variable:
import someImg from "../../public/svg/some_img.svg"
src={someImg}
this is the solve for the question, config required for to specify path:
module: {
...
rules: [
{
test: /\.(png|jpg|gif|svg|ico)$/,
loader: 'file-loader',
query:{
outputPath: './img/',
name: '[name].[ext]?[hash]'
}
}
...
]
}

Unexpected character '#' in #import at webpack config

So right now I am having the issue I set up my webpack config as such
var webpack = require('webpack');
var path = require('path');
var parentDir = path.join(__dirname, '../');
module.exports = {
entry: [
path.join(parentDir, 'index.js')
],
module: {
rules: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader'
}, {
test: /\.less$/,
loaders: ["style-loader", "css-loader", "less-loader"]
}, {
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
}]
},
output: {
path: parentDir + '/dist',
filename: 'bundle.js'
},
devServer: {
contentBase: parentDir,
historyApiFallback: true
}
}
The error that I am getting is
Module parse failed: Unexpected character '#' (11:0)
You may need an appropriate loader to handle this file type.
| *
| */
| #import url(https://fonts.googleapis.com/css?
family=Lato:400,700,400italic,700italic&subset=latin);/*!
I know I need to add a rule for this import I am just not sure which kind I am new to webpack and can't find anything referencing this type, also this #import exists in the semantic-ui-css package
Adding this bit to modules in the config file seemed to do the trick:
{
test: /\.css$/,
use: [
'to-string-loader',
'css-loader',
'resolve-url-loader'
]
}

Webpack load image inside of HTML

Somewhere in the middle of my Angular template I have img tag:
<img src="../../images/error.gif" />
Until now I was using raw-loader with this simple configuration:
test: /\.html/,
loader: 'raw'
But after i read this i decide I need a change:
The raw-loader is supposed to turn a text file into a CommonJS module
that exports the file contents as a string – nothing more.
What did I change:
So I changed my raw-loader to html-loader based on this article and this question.
{
test: /\.html$/,
loader: [
"html?" + JSON.stringify({
attrs: ["img:src", "img:ng-src"]
})
]
}
And this: loader
{ test: /.gif$/, loader: "file" }
Based on this and this questions I added publicPath: "/assets" to my webpackconfig.
And changed img tag on <img src=" { require('/assets/logo.png') } " />
My webpackconfig looks like:
webpack({
entry: path.resolve(__dirname, './main.js'),
output: {
path: dir_dist,
filename: 'custom-shared-lib.js',
publicPath: "/assets"
},
module: {
preLoaders: [
{
test: dir_bin,
loader: path.resolve(__dirname, "./my-loader.js"),
query: JSON.stringify(preLoaderQuery)
},
],
loaders: loader
},
plugins: [
// Avoid publishing files when compilation fails
new webpack.NoErrorsPlugin()
],
}, function(err, stats) {
console.log(stats.toString());
});
While variabile loaders are:
[
{
test: /\.js$/,
include: [dir_bin, dir_src],
loader: 'babel-loader',
query: {
presets: ['es2015']
}
},
{
test: /\.html$/,
loader: [
"html?" + JSON.stringify({
attrs: ["img:src", "img:ng-src"]
})
]
},
{ test: /.gif$/, loader: "file" }
]
Error:
This error happen while compiling:
Module not found: Error: Cannot resolve 'file' or 'directory' ./ {
require('/assets/error.gif') }
I would be happy for any advice.

Webpack - Error: Cannot define 'query' and multiple loaders in loaders list

This error appeared after I added the react-hot loader in an array following this tutorial: https://thoughtbot.com/blog/setting-up-webpack-for-react-and-hot-module-replacement
I'm getting Error: Cannot define 'query' and multiple loaders in loaders list.
var WebpackDevServer = require("webpack-dev-server");
var webpack = require('webpack');
var path = require('path');
require("babel-polyfill");
var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'src');
module.exports = {
entry: [
'babel-polyfill',
'bootstrap-loader',
'webpack/hot/dev-server',
APP_DIR + '/import.js',
],
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
loaders: ['react-hot', 'babel'],
exclude: /node_modules/,
query: {
plugins: ['transform-runtime'],
presets: ['es2015', 'stage-0', 'react']
}
}, {
test: /\.css$/,
loader: "style-loader!css-loader"
}, {
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}, {
test: /\.(png|woff|woff2|eot|ttf|svg|jpg|gif)$/,
loader: 'url-loader?limit=100000'
}]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
};
It seems that the query is an alternative way of customizing the behaviour of a single loader, that is cleaner than specifying those parameters inline (see below). If multiple loaders are present, Webpack does not know to which the query configuration applies.
The following should solve your problem:
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['react-hot', 'babel?presets[]=es2015,presets[]=stage-0,presets[]=react,plugins[]=transform-runtime']
}
EDIT: While this solution works for Webpack 1, see the other answers for cleaner solutions that work in more recent versions.
My Solution:
loaders: [{
test: /\.(js|jsx)$/,
loaders: ['react-hot', 'babel?' + JSON.stringify({
cacheDirectory: true,
plugins: [
'transform-runtime',
'transform-decorators-legacy'
],
presets: ['es2015', 'react', 'stage-0'],
env: {
production: {
presets: ['react-optimize']
}
}
}), 'eslint'],
include: src,
exclude: /node_modules/
}
In webpack 2 & 3 this can be configured much more cleanly.
Loaders can be passed in an array of loader objects. Each loader object can specify an options object that acts like the webpack 1 query for that particular loader.
For example, using both react-hot-loader and babel-loader, with babel-loader configured with some options, in webpack 2/3
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'react-hot-loader'
}, {
loader: 'babel-loader',
options: {
babelrc: false,
presets: [
'es2015-native-modules'
'stage-0',
'react'
]
}
}]
}]
}
For comparison, here is the same configuration in webpack 1, using the query string method.
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loaders: [
'react-hot',
'babel-loader?' +
'babelrc=false,' +
'presets[]=es2015,' +
'presets[]=stage-0,' +
'presets[]=react'
]
}]
}
Notice the changed property names all down the chain.
Also, note that I changed the es2015 preset to es2015-native-modules preset in the babel-loader configuration. This has nothing to do with the specification of options, it's just that including es6 modules allows you to use webpack tree-shaking feature introduced in v2. It could be left alone and it would still work, but the answer would feel incomplete without that obvious upgrade being pointed out :-)
Disclaimer: This is the same as my answer to a similar question, but this question has similar votes/views/google ranking, so I'll post the answer here too.
For webpack 2. I manage to configure like this:
var webpack = require("webpack");
var path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist/assets"),
filename: "bundle.js",
publicPath: "/assets/"
},
devServer: {
inline: true,
contentBase: './dist',
port: 3000
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: "babel-loader",
options: {
presets: ['latest', 'react', 'stage-0']
}
}
]
}
};
This solution worked for me:
module: {
loaders:[
{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel-loader'
}
]
}
and presets in the .babelrc
{
'presets': ['latest', 'react', 'stage-0']
}
please refer to https://webpack.github.io/docs/usage.html
I had faced the same issue since I found a solution for myself. you can try it:
--- here is the solution ---
If you've defined "presets" in ".babelrc" file
then you don't need to specify it in the "webpack.config.js" file, then delete it and it works well
and if you don't,
I recommend you to go to your ".babelrc" file and specify your presets there

Webpack sass loader with sourcemaps and url statements

I have read that in order to have source maps, I have to use absolute urls in the url('') statement.
I did it this way :
body
background-image: url('/elements/assets/tmp_background.jpg')
It works when I remove the sourceMap option from the css loader, it does not if I activate it.
I think I might have failed somewhere on the absolute path point, do you have any ideas?
Here is my config file :
module.exports = {
devtool: 'source-map',
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
path.resolve(__dirname, 'elements/main.js'),
],
output: {
path: 'dist',
publicPath: '/', // Prefix for all the statics urls
filename: 'bundle.js',
},
resolve: {
root: path.resolve(__dirname),
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader?presets[]=es2015',
},
{ test: /\.css$/, loaders: ['style', 'css'] },
{ test: /\.scss$/, loaders: ['style', 'css?sourceMap', 'sass?sourceMap'] },
{ test: /\.sass$/, loaders: ['style', 'css?sourceMap', 'sass?sourceMap&indentedSyntax=true'] },
{ test: /\.jade$/, loaders: ['ngtemplate', 'html', 'jade-html'] },
{ test: /\.(png|gif|jp(e)?g)$/, loader: 'url-loader?limit=8192' },
{ test: /\.(ttf|eot|svg|woff(2))(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=50000' },
],
},
};
On a more general idea, I could not find a working example of what I'm trying to do. I would be very interested if you can redirect me to that.
The publicPath can be used to fix this, until a cleaner solution appears.
See https://github.com/webpack/css-loader/issues/29

Categories