I have decided to give it a try to Webpack 2. I'm trying to bundle js and css.
The problem is that CSS in not being applied the elements on the page (it is present in the built file).
This is the app structure:
app
|-styles.css
|-app.js
build
|-bundle.js
index.html
webpack config file:
var path = require('path');
module.exports = {
entry: './app/app.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: 'css-loader'
}
]
}
}
index.html:
<html>
<head>
<script src="./build/bundle.js"></script>
</head>
<body>
<div class="abc"> hello </div>
</body>
app.js:
require('./styles.css');
console.log('js loaded!');
When I run build command getting this output:
[0] ./app/styles.css 240 bytes {0} [built] [1] ./~/css-loader/lib/css-base.js 1.51 kB {0} [built] [2] ./app/app.js 148 bytes {0} [built]
Also I can see the css is included in the bundle.js file
exports.push([module.i, ".abc {\r\n width: 300px;\r\n height: 100px;\r\n background-color: red;\r\n}", ""]);
If I include css file in html it works fine so I guess there is no spelling mistake in CSS itself. I spent quite a lot of time trying to figure it out. Is there anything I'm missing?
You're loading the CSS as a string with just css-loader. You'll need style-loader as well in order to have the CSS load into the DOM when you import it.
use: [ 'style-loader', 'css-loader' ]
Related
here is my code:
{
test: /\.ttf$/,
use: [
{
loader: 'ttf-loader',
options: {
name: './font/[hash].[ext]',
},
},
]
}
and tried with,
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader',
],
},
]
},
still gives this problem:
ERROR in ./src/client/assets/fonts/blacky.TTF 1:0
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
# ./src/client/pages/Home/Homepage.module.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss) 4:36-76
# ./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss
I am aiming to convert my react app into an ssr app for firebase.
entire config file::
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins:
[
new MiniCssExtractPlugin({
filename:"[name].css",
chunkFilename:"[id].css"}),
],
entry: {
"app": "./src/client/index.js",
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
exclude: /node_modules/,
},
{
test: /\.js$/,
loader: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
loader: 'url-loader',
options: {
limit: 10000
}
},
{
test: /\.ttf$/,
use: [
{
loader: 'ttf-loader',
options: {
name: './font/[hash].[ext]',
},
},
]
}
]
},
output: {
path: __dirname+"/functions/Views/public",
filename: "bundle.js",
},
}
(other problem that wasnt mentioned but still persits/ a lot more of the cmd error log)
r{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}#media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}#page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
| /*# sourceMappingURL=bootstrap.min.css.map */
# ./src/client/pages/Header/navbar.js 15:0-46
# ./src/client/pages/Header/Header.js
# ./src/client/pages/about.js
# ./src/client/App.js
# ./src/client/index.js
Child mini-css-extract-plugin node_modules/style-loader/dist/cjs.js!node_modules/css-loader/dist/cjs.js!node_modules/sass-loader/dist/cjs.js!src/client/pages/Home/Homepage.module.scss:
Entrypoint mini-css-extract-plugin = *
[0] ./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss 1.04 KiB {0} [built]
[2] ./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss 404 bytes {0} [built]
[5] ./src/client/assets/fonts/blacky.TTF 284 bytes {0} [built] [failed] [1 error]
+ 3 hidden modules
ERROR in ./src/client/assets/fonts/blacky.TTF 1:0
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
# ./src/client/pages/Home/Homepage.module.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss) 4:36-76
# ./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/client/pages/Home/Homepage.module.scss
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! AllianceCareLTD#0.2.0 webpack: `webpack-cli --config webpack.config.js`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the AllianceCareLTD#0.2.0 webpack script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\User\AppData\Roaming\npm-cache\_logs\2020-10-15T13_04_02_184Z-debug.log
A bit late but still worth to mention for anybody facing this issue. I was also spending some time with this topic and trying out many different things. And as I see all these inspired discussions in different forums, I can imagine that many new programmers are struggling with this topic. In the end I found a solution which worked for me. I hope it works for you, too.
FIRST
I use an outputPath for my fonts. It'll duplicate the font files, and place them into whatever directory in the "dist" folder depending on what we specify using outputPath - e.g. a path called "fonts". This is required for our fonts to be referenced correctly within your style file; for example scss or .js if you use styled-components and create a 'createGlobalStyle'. It also defines the relative paths for the output content which will be prefixed to every url request. In my case I use "fonts/". Example: If I implement font family yxz.woff, the path for the user in the frontend will be localhost:3000/fonts/yxz.woff in my case. It has nothing to do with my real folder structure in my project (see next paragraph).
// Webpack setting
{
test: /\.(woff|woff2|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "fonts/",
},
},
],
},
The font yxz.woff is placed directly in my public folder in the root directory. Any other placement can also be used (e.g. src/styles/fonts/yxz.woff) and works in my case. Figure it out for your project.
In the next step I define and load the yxz font with a .js file with styled-components. But scss works also in my case. Important here! You have to import every source (woff, woff2, ttf) separately and give it an unique name. See my following example
import { createGlobalStyle } from "styled-components";
import yxzWoff2 from "../../../public/yxz.woff2";
import yxzWoff from "../../../public/yxz.woff";
export default createGlobalStyle`
#font-face {
font-family: 'yxz';
src: local('yxzWoff2'),
url("fonts/yxz.woff2") format('woff2');
src: local('yxzWoff'),
url("fonts/yxz.woff") format('woff');
font-weight: normal;
font-style: normal;
font-display: auto;
}
`;
As you can see, I use the same paths as defined with webpack via outputPath. Still it is directly placed in the public folder. You can of course apply the above principle for ttf, too. However, in my case I mainly use woff and woff2.
I meanwhile have a quite large collection of fonts in the fonts folder structure in my project and it works. I hope this solves your issue and saves you and others here time.
This is my webpack configuration:
const path = require('path');
module.exports = {
entry: './src/entry.jsx',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
include: path.resolve(__dirname, 'src'),
query: {
presets: ['es2015', 'react']
}
},
],
// rules: [],
}
};
Notice that the rule array is commented out.
When I build webpack with the following JS:
import React from "react";
import ReactDOM from "react-dom";
ReactDOM.render(
<h1>Hello, World!</h1>,
document.getElementById('app')
);
It works just fine. But when I uncomment the rules array, I'm given the following error:
ERROR in ./src/entry.jsx
Module parse failed: Unexpected token (6:4)
You may need an appropriate loader to handle this file type.
|
| ReactDOM.render(
| <h1>Hello, World!</h1>,
| document.getElementById('app')
| );
But with the rule array commented out, it gives me this:
> webpack
Hash: 96711291c47522e3cd46
Version: webpack 3.10.0
Time: 1221ms
Asset Size Chunks Chunk Names
bundle.js 727 kB 0 [emitted] [big] main
[14] ./src/entry.jsx 484 bytes {0} [built]
+ 26 hidden modules
With no errors.
I need that rule array because I have some dependencies that need me to add things to that array.
According to the currect docs on webpack v3 (https://webpack.js.org/configuration/module/), the module section doesn't have a loaders key anymore, but only rules.
I suspect in your case loaders overwrite rules due to backwards compatibility with older versions of webpack
So renaming loaders to rules should be sufficient to solve the problem
Good luck
I have the following webpack.config.js file:
'use strict';
let path = require('path');
let webpack = require('webpack');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: [
'./index.js'
],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
devtool: 'inline-source-map',
watch: true,
module: {
rules: [
{
test: /\.jsx?$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: [ 'style-loader', 'css-loader?modules', ],
publicPath: '/dist'
})
},
{
test: /\.ejs$/,
use: 'ejs-compiled-loader'
}
],
},
plugins: [
new ExtractTextPlugin({
filename: 'styles.css'
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
minify: {
collapseWhitespace: true
},
hash: true,
template: 'ejs-render-loader!./views/index.ejs'
}),
]
};
When trying to load an ejs file that contains <% somefile %> the file cannot be found.. this is the error I receive:
Child html-webpack-plugin for "index.html":
Asset Size Chunks Chunk Names
index.html 26.2 kB 0
chunk {0} index.html 554 bytes [entry]
[./node_modules/ejs-render-loader/index.js!./views/index.ejs] ./~/ejs-render-loader!./views/index.ejs 554 bytes {0} [built] [failed] [1 error]
ERROR in ./~/ejs-render-loader!./views/index.ejs
Module build failed: Error: ENOENT: no such file or directory, open 'head.ejs'
at Object.fs.openSync (fs.js:584:18)
at fs.readFileSync (fs.js:491:33)
at Object.exports.parse (/var/www/rio-olympics-3/monitor/node_modules/ejs-compiled-loader/node_modules/ejs/lib/ejs.js:168:19)
at Object.exports.compile (/var/www/rio-olympics-3/monitor/node_modules/ejs-compiled-loader/node_modules/ejs/lib/ejs.js:245:15)
at Object.module.exports (/var/www/rio-olympics-3/monitor/node_modules/ejs-compiled-loader/index.js:7:22)
webpack: Failed to compile.
I have tried many file path formats, and none of them worked, here is my ejs file with my head.ejs in the same folder:
<!DOCTYPE html>
<html lang="en">
<% include head %>
<body>
<div id="navbar-app"></div>
<p> Welcome, more coming soon! </p>
</body>
<!-- insert component scripts below here -->
<script src="dist/js/NavBarMain.js"></script>
</html>
You have two different loaders configured for the index.ejs, which results in a clash.
A general rule for all .ejs:
{
test: /\.ejs$/,
use: 'ejs-compiled-loader'
}
An inline rule for the template in html-webpack-plugin:
template: 'ejs-render-loader!./views/index.ejs'
If you only want to use the inline loader you can add a leading !, so webpack won't apply other loaders:
template: '!ejs-render-loader!./views/index.ejs'
The above fixes your problem, but it is a little questionable why you have two different ejs loaders. To be honest I'm not fully aware of the differences in the loaders since both point to the same GitHub repository, although it seems to me like ejs-render-loader is just an earlier version. They actually handle the includes differently, that's why you get the error.
From the example in Usage of ejs-compiled-loader:
// Child Templates
// path is relative to where webpack is being run
<%- include templates/child -%>
That means if you want to use the ejs-compiled-loader for all .ejs you need to change the include to:
<% include views/head %>
And you can get rid of the inline loader in the html-webpack-plugin:
template: './views/index.ejs'
It's up to you whether you want to change this, I would just try to avoid loader conflicts and I don't think ejs-render-loader will be updated anymore.
In fact there is a v2.2.0 of ejs-compiled-loader which went back to the other include behaviour, relative to the current file, which is definitively more intuitive. You can install it with:
npm install --save-dev ejs-compiled-loader#2.2.0
I'm having some issues getting Webpack's live reloading working. I believe I have everything setup correctly. The problem is when saving files the browser refreshes but no changes are displayed.
I run the webpack development server with the following command:
webpack-dev-server --inline
And I start my PHP development server with this command:
php -S localhost:8000 -t public/
In my public/index.php file include the webpack-dev-server.js file:
<script src="http://localhost:8080/webpack-dev-server.js"></script>
When I make a changes to entry.js and hit save I can see the files recompiling and the browser refreshes. Except no changes are made.
I get the following output at the terminal when saving entry.js:
Time: 44ms
Asset Size Chunks Chunk Names
app.js 240 kB 0 [emitted] main
app.css 42.4 kB 0 [emitted] main
chunk {0} app.js, app.css (main) 222 kB [rendered]
[75] ./src/js/entry.js 108 bytes {0} [built]
+ 77 hidden modules
webpack: bundle is now VALID.
webpack: bundle is now INVALID.
Hash: 3937d6fc90a1794a8daa
Version: webpack 1.13.3
I tried to add a simple alert("Testing"); to entry.js but got no popup. If I check the webpack-dev-server.js file for any line that contains the word Testing it finds non.
Here is the contents of webpack.config.js:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const path = require('path');
module.exports = {
context: __dirname,
entry: path.join(__dirname, '/src/js/entry.js'),
output: {
path: path.join(__dirname, '/public'),
filename: "app.js"
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel',
query: {
presets: ['es2015']
}
},
{ 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" }
]
},
postcss: [
require('postcss-import'),
require('postcss-nested'),
require('autoprefixer'),
require('precss'),
require('postcss-custom-media'),
require('lost')
],
plugins: [
new ExtractTextPlugin('app.css')
]
};
Is there anything I'm doing wrong?
Edit: Also tried the following:
php -S localhost:8000 -t public starts the webserver. webpack-dev-server --content-base=public --inline --hot --watch" starts the webpack-dev-server. I load localhost:8000/index.php and monitor the console inspector. I can see that hot module replacement is enabled. If I modify and save entry.js and include a simple alert('Hello'); I can see in the web console that it's recompiling. The page refreshes, yet nothing happens. No changes to be seen.
I've been working on an app using React and Webpack for a little while. My development environment works fine, and everything loads properly using webpack-dev-server.
I decided to run a production build of the application to see what the end-product might look like size-wise and observe the general output of the webpack product build.
It turns out that running webpack -p, while it does produce output (more on that in a minute), does not load anything at all when I hit the site in a browser.. A quick check of the output tells me that none of my component code is making it into the webpack -p build.
The images and HTML copy over as they exist in my src (dev) folder, however my JS bundle output is extremely small - the file (main.js) is only 246 bytes.
Here is the output from running webpack -p
$ npm run build
> project#0.1.0 build /Users/me/Development/project
> NODE_ENV=production webpack -p --bail --progress --config webpack.config.babel.js
Hash: 9e5f6974ce21c920a375
Version: webpack 1.12.10
Time: 2003ms
Asset Size Chunks Chunk Names
index.html 1.45 kB [emitted]
images/edit.svg 524 bytes [emitted]
images/search.svg 1.19 kB [emitted]
main.js 246 bytes 0, 1 [emitted] javascript, html
+ 219 hidden modules
When I run the development version of the project, the output is markedly different... I know that the dev server dependencies are in there, and the code is not minified.. And, most importantly - everything works as expected when running the dev server.
$ npm start
> project#0.1.0 start /Users/me/Development/project
> webpack-dev-server --hot --display-modules --config webpack.config.babel.js
http://localhost:3333/
webpack result is served from /
content is served from /Users/me/Development/project/dist
Hash: 1b34ed58f9e323966ada
Version: webpack 1.12.10
Time: 2745ms
Asset Size Chunks Chunk Names
index.html 1.45 kB [emitted]
images/edit.svg 524 bytes [emitted]
images/search.svg 1.19 kB [emitted]
main.js 1.54 MB 0, 1 [emitted] html, javascript
Here's my webpack.config.babel.js file:
import webpack from 'webpack';
import path from 'path';
import ModernizrWebpackPlugin from 'modernizr-webpack-plugin';
import modernizrConfig from './modernizr.config';
const appDir = path.resolve(__dirname, './src');
const distDir = path.resolve(__dirname, './dist');
const nodeModulesDir = path.resolve(__dirname, './node_modules');
const excludeDirs = /(node_modules|bower_components)/;
module.exports = {
entry: {
javascript: appDir + '/main.js',
html: appDir + '/index.html'
},
output: {
path: distDir,
filename: 'main.js',
},
devServer: {
contentBase: distDir,
inline: true,
port: 3333
},
resolve: {
extensions: ['', '.js', '.es6'],
modulesDirectories: [
'node_modules',
'./src'
]
},
plugins: [
// new webpack.optimize.CommonsChunkPlugin('common.js'),
// new ModernizrWebpackPlugin(modernizrConfig),
],
sassLoader: {
sourceMap: false,
includePaths: [
appDir,
nodeModulesDir,
nodeModulesDir + '/breakpoint-sass/stylesheets/',
nodeModulesDir + '/susy/sass'
]
},
module: {
loaders: [
{ // js/jsx
test: /\.js?$/,
exclude: excludeDirs,
loader: 'babel',
query: {
cacheDirectory: true,
presets: [
'es2015', 'react'
]
}
},
{ // html
test: /\.html$/,
exclude: excludeDirs,
loader: 'file?name=[name].[ext]'
},
{ // images
test: /\.(gif|png|jpg|jpeg|svg)$/,
exclude: excludeDirs,
loader: 'file?name=images/[name].[ext]'
},
{ // sass
test: /\.scss$/,
exclude: excludeDirs,
loader: 'style!css!sass'
}
]
}
}
I don't think I've got a particularly complex, or uncommon setup, and I've tried changing everything from es2015/es6 to commonJS already as well, with the same result.
I'm at a loss as to what the issue could possibly be here; hoping that someone can point out some obvious error I've got, or perhaps suggest config updates/changes that could resolve this problem.
Thanks for taking the time to read everything!
As I mentioned in my comment, I've been using webpack successfully for months now, and I've never come across using an HTML file as an entry point.
Usually you'll use Webpack to package up javascript, css, and sometimes images (ie: "assets") to be used by an html file. Serving that HTML file is outside the realm of Webpack's responsibility.
I would suggest using Webpack to generate only the final javascript bundle, then using some other method (ie: express, or some other web server) to serve that file and the html that consumes it.