I am using the new asset module instead of loader-file but I have a problem because it creates two folders. It seems that is a easy stuff but I spent a lot of time searching and I can't get any solution. Here is my webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
module.exports={
entry:'./src/index.js',
output:{
path:path.resolve(__dirname ,'build'),
filename: 'javascript/[name].js',
assetModuleFilename: '../images/[name][ext]'
},
module:{
rules:[
{
test: /\.scss$/,
use:[
// Creates `style` nodes from JS strings
{loader : MiniCssExtractPlugin.loader },
// Translates CSS into CommonJS
{loader:"css-loader"},
// Compiles Sass to CSS
{loader:"sass-loader"}
]
}, {
test: /\.(png|jpg|gif)/,
type: 'asset/resource'
}
]
},
plugins:[new HtmlWebpackPlugin({
template: './src/index.html'
}), new MiniCssExtractPlugin({
filename: 'style/style.css'
})]
}
the structure of my file are:
-src
-images
*logoface.png
-scss
*style.scss
*package.json
*webpack.config.js
*package-lock.json
the result structure is:
-build
-images
*logoface.png
-javascript
*main.js
-style
*style.css
*index.html
-images
*logoface.png
Here my package.json, you can see the build-test where I delete the extra folder. I want the right solution. thanks a lot for your help I am still learning.
{
"name": "testingNodeJs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode development --watch",
"build-test": "webpack --mode development && rm -fr images",
"build-dev": "webpack --mode development --watch && rm -fr images"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"copy-webpack-plugin": "^7.0.0",
"css-loader": "^5.1.0",
"html-webpack-plugin": "^5.2.0",
"mini-css-extract-plugin": "^1.3.9",
"sass": "^1.32.8",
"sass-loader": "^11.0.1",
"style-loader": "^2.0.0",
"webpack": "^5.24.2",
"webpack-cli": "^4.5.0"
}
}
I solved it, I changed the assetModuleFilename: '../images/[name][ext]' to assetModuleFilename: 'images/[name][ext]' and then changed the configuration of MiniCssExtractPlugin with:
module: {
rules:[
{
test: /\.(scss)$/i,
use:[
{
loader : MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
}
},
"css-loader",
"sass-loader"
]
},
{
test: /\.(png|jpg|jpeg|gif)/,
type: 'asset/resource'
},
]
},
where the public path is
publicPath: '../'
I hope it helps anyone else.
Related
I have a html file in src folder. I have installed html-loader and html-webpack-plugin to generate an updated html in dist folder. Using npm run build will generate a new html file in dist folder but I don't want to run same command each time and want to work in real time updates so I used npm start and it opens a browser window with html from src folder but it never generates a new html file in dist folder and even if I manually make a new html there, browser window will never be updated. So I am stuck with html from src folder (and since I am using static: ./dist even that won't be updated).
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { title } = require("process");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
clean: true,
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
title: "todo-app",
}),
],
devtool: "inline-source-map",
devServer: {
static: "./dist",
},
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.html$/i,
use: ["html-loader"],
},
],
},
};
Package.json
{
"name": "todo-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"start": "webpack serve --open"
},
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^6.6.0",
"html-loader": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.68.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
}
}
I am new to webpack. I am making a react application which will read text from an external config.js file and display it on the UI. I am trying to have a external config.js file which I dont want to be bundled but be required during run time.
This is my webpack.config.js:
const path = require('path');
const html_plugin = require("html-webpack-plugin");
module.exports = {
mode: 'development',
entry: './src/app.js',
output: {
path: path.resolve(__dirname,'build'),
filename: 'build.js'
},
externals: {
config: './config.js',
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
},
plugins: [new html_plugin({ template: './src/index.html' })]
}
The config.js is in the same directory as webpack.config.js.
This is my config.js:
module.exports = {
title: 'ssup'
}
This is how I am using my config.js in a component:
import config from 'config';
class ... {
return <h1>{config.title}</h1>
}
Here is my project structure:
- src/
- webpack.config.js
- config.js
When I try to run this application, it shows the following error in my chrome console:
the line 681 in build.js contains this:
eval("module.exports = ./config.js;\n\n//# sourceURL=webpack:///external_%22./config.js%22?");
Here is my package.json:
{
"name": "react-from-scratch",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --open",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.10.2",
"react-dom": "^16.10.2"
},
"devDependencies": {
"#babel/core": "^7.6.4",
"#babel/preset-env": "^7.6.3",
"#babel/preset-react": "^7.6.3",
"babel-loader": "^8.0.6",
"css-loader": "^3.2.0",
"html-webpack-plugin": "^3.2.0",
"style-loader": "^1.0.0",
"webpack": "^4.41.1",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2"
}
}
what am I doing wrong?
You don't need any webpack configuration to do that. Save your config as JSON and fetch it at runtime instead of build time.
Also, what are you trying to achieve using this technique? What is your use case?
I have two npm commands "build": "webpack --mode production" and "start": "webpack-dev-server --mode development --open". When I run the start command the web application runs as intended with all the CSS and javascript being transpiled correctly.
However when I run build the fils are generated as intended and when the main HTML file is opened the href and src do not point to the correct directories.
I looked at my webpack.config.js and it appears to be working as intended which leads me to a bit of head-scratching. Changing the HTML template causes the development version to break and have the production version work as intended. The intention is for both development and production version to work as intended.
For reference here is my directory structure:
root
|-.vscode
|-dist
| |-css
| |-img
| |-js
| |- output location for bundle.js index.html main.css
|-node.modules
|-src
|-css
| |-scss
|-js
| |-JSON
| |-models
| |-view
| |-app.js
|-index.html
|-.babelrc
|-package-lock.json
|-package.json
|-webpack.config.js
Webpack config file
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const babelLoader = require("babel-loader");
module.exports = {
entry: [
"babel-polyfill","./src/js/app.js"
],
output: {
path: path.resolve(__dirname, "dist/js"),
filename: "bundle.js",
},
devServer: {
contentBase: "./dist"
},
plugins: [
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
filename:"index.html",
template:"./src/index.html"
})
],
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env"]
}
}
},
{
test: /\.scss$/,
use: [{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader",
options: {
sourceMap: true,
modules: true,
localIdentName: "[local]"
}
},
"sass-loader"
]
}
]
}
}
and package.json
{
"name": "tempName",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"start": "webpack-dev-server --mode development --open"
},
"author": "Fake Name",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.7.2",
"#babel/preset-env": "^7.7.1",
"babel-loader": "^8.0.6",
"chart.js": "^2.9.3",
"css-loader": "^2.1.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"gulp-babel": "^8.0.0",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.7.0",
"node-sass": "^4.13.0",
"sass-loader": "^7.3.1",
"sortablejs": "^1.10.1",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
},
"dependencies": {
"axios": "^0.19.0",
"babel-polyfill": "^6.26.0",
"pokedex-promise-v2": "^3.2.0"
}
}
How do I specify the href(s) and src(s) in the HTML document to link to the CSS and javascript since they are added during the build script and are not in the HTML template?
Try these things:
1) instead of setting contentBase to dev-server try to set 'publicPath: '/'
2) set 'output.publicPath' to '/' also
3) if previous doesn't work, HtmlWepbpackPlugin has base option to add prefix for loaded scripts. but i strongly recommend to handle it with public path.
PS: fix your prod build, and only when fix webpack-dev-server. it will be easier
So basicaly I can't get any of my javascript to work after linking bundle.js onto my index.html. Every function is undefined even tho bundle.js is being loaded and I can access it via source code in dev tools. However if I link my javascript file "app.js" directly everything works as intended. I figured there will most likely be a problem with my webpack setup since this is my first time setting it up. I'll be glad for any other tips regarding this webpack.config. Thanks in advance :)
Here is my package.json:
{
"name": "name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"dev": "webpack --mode development",
"devs": "webpack-dev-server --mode development"
},
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^1.0.0",
"extract-loader": "^3.0.0",
"file-loader": "^2.0.0",
"font-awesome": "^4.7.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.4.4",
"node-sass": "^4.9.4",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.23.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
}
}
webpack.config.js:
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
main: ["./src/index.js"]
},
output: {
filename: "scripts/bundle.js",
path: path.resolve(__dirname, "./dist")
},
module: {
rules: [
{
test: /\.html$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].html"
}
},
{
loader: "extract-loader"
},
{
loader: "html-loader",
options: {
attrs: ["img:src"]
}
}
]
},
{
test: /\.sass$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
},
{
test: /\.(jpg|gif|png)$/,
use: [
{
loader: "file-loader",
options: {
name: "images/[name].[ext]"
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "styles/[name].css",
chunkFilename: "[id].css"
})
],
watch: true,
};
main webpack entry index.js:
require('./scripts/app.js');
require('./styles/sass/app.sass');
require("./index.html");
index.html script link:
<script src="./scripts/app.js"></script>
EDIT Problem is definitely within bundle.js that is being generated. If I copy the function at the begining of the bundle.js everything works as intended. Here is bundle.js code in fiddle:
https://jsfiddle.net/ustqkg7v/
If I copy the function from app.js at the beginning of the bundle.js, everything works as intented. I think there might be a problem with scope but I am not sure.
EDIT 2 I've setup smaller project with same folder structure, files, etc. Exactly the same issue. Here is link:
https://www.dropbox.com/s/9f5pf6y4fbb60dw/webpack4-test.rar?dl=0
The issue may be also because of this path: path.resolve(__dirname, "./dist").I am assuming the webpack.config.js is at the root level of the project so I think it has to be path: path.resolve(__dirname, "dist")
Then in html it need to be referred from dist folder
<script src="./dist/app.js"></script>
Before this check if app.js is getting generated in dist folder
Here is my webpack.config.js code...
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: ['webpack/hot/dev-server', 'babel-polyfill', './src/main.jsx'],
output: {
path: "./build",
filename: "main.js"
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader', // 'babel-loader' is also a legal name to reference
query:
{
presets:['es2015', 'react']
}
}
]
},
resolve: {
extensions: ['', '.js', '.jsx']
}
}
Here is my package.son file....
{
"name": "udemy-react",
"version": "0.0.1",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev": "webpack-dev-server --devtool eval --progress --colors --hot -- content-base build"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.2.1",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
"react-hot-loader": "^1.3.0",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.0"
}
}
After I run npm run dev, I will have my main.js file conevert from .jsx file and everything goes well on localhost:8080.
My question is, why i cannot directly use .js file without running on web pack server?
Because I directly include main.js file in my .html and open in browser, and I got
Uncaught Error: [HMR] Hot Module Replacement is disabled.
I thought web pack already conevert everything for me , so I can directly use it.
What I should do if I want to make a production enviorment?