I'm need to use webpack as a script (not the typical config file) and be able to support css imports, however webpack/style-loader does't seem to be able to load a css import when it's outside the root directory.
directoryA/package.json
{
"name": "poc",
"version": "1.0.0",
"description": "",
"main": "poc.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"style-loader": "^0.28.8",
"style-loader": "^0.19.1",
"webpack": "^3.10.0"
}
}
directoryA/poc.js
const path = require("path");
const webpack = require("webpack");
let appPath = process.env.PWD;
webpack({
entry: path.join(appPath, 'app.js'),
context: appPath,
output: {
libraryTarget: 'umd',
path: path.join(appPath, 'out'),
filename: 'app.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
}
}).run(() => {
console.log("done");
});
directoryB/app.js
import './foo.css';
directoryB/foo.css
body { background-color: blue; }
directoryB/out/index.html
<html>
<head><script src="app.js"></script></head>
<body></body>
</html>
steps to replicate:
cd directoryB/
node ../directoryA/poc.js
then open directoryB/out/index.html in the browser
result: "Error: Cannot find module "./foo.css"
expected: loading css style and getting a blue page
Note that, if out/index.html , app.js and foo.cs are inside directoryA instead, then running node poc.js actually yields the expected result, however outside, webpack or style-loader can't seem to find the file (note: also tried to use the modules: directive. both cases work if using importing a js file)
Related
I'm trying to run through the "Getting Started" section in Webpack's documentation here. I'm at the section before loading images - the .html file loads as expected ("Hello webpack" in red text) when I open it on Mozilla Firefox, but I get an Uncaught SyntaxError: Invalid or unexpected token (at bundle.js:2:8083) when I open it with Chrome. I'll include my index.js, dist/index.html, package.json, and webpack.config.js below:
index.js:
import _ from 'lodash';
import './style.css';
function component() {
const element = document.createElement('div');
// Lodash, now imported by this script
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
element.classList.add('hello');
return element;
}
document.body.appendChild(component());
dist/index.html
<!doctype html>
<html>
<head>
<title>Asset Management</title>
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
package.json
{
{
"name": "Webpack Demo",
"version": "0.0.0",
"license": "MIT",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js"
},
"dependencies": {
"lodash": "^4.17.21",
"three": "^0.140.0"
},
"devDependencies": {
"css-loader": "^6.7.1",
"style-loader": "^3.3.1",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2"
}
}
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
};
Please let me know if you can figure out what I'm doing wrong! Thanks
I keep getting error Uncaught ReferenceError: require is not defined in browser even with Webpack and Babel. For some reason I never had to worry about this before. I'm not sure if this error is caused by updated packages or what. I set up a very simple test application for simplicity.
package.json
{
"name": "require-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"engines": {
"node": "16.16.0"
},
"scripts": {
"build": "webpack --config webpack.config.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.18.10",
"#babel/preset-env": "^7.18.10",
"babel-loader": "^8.2.5",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
}
}
webpack.config.js
const path = require('path');
module.exports = {
target: "node",
mode: "production",
output: {
path: path.resolve(__dirname, 'dist'),
clean: true,
filename: (pathData) => {
return 'index.js'
},
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
}
]
}
}
src/index.js (js file before build)
const path = require('path');
console.log(path);
dist/index.js (js file after build)
(()=>{var r,e={17:r=>{"use strict";r.exports=require("path")}},t={};r=function r(o){var s=t[o];if(void 0!==s)return s.exports;var p=t[o]={exports:{}};return e[o](p,p.exports,r),p.exports}(17),console.log(r)})();
There're a few things on your code needing changed. First of all, you can't target to build for node while you run that code on browser which is wrong. Secondly, path is designed and built to run on node server specifically, however, there's a fallback for path on browser though which is called path-browserify. You can check its document to see how it works.
Anyway to sum up, you need to switch target as web in the end:
module.exports = {
target: "web",
// ...
}
I don't seem to understand how webpack works. I would like to create a plain javascript library with some reusable components that I can use in other applications and in script tags in the html. So I tried to make a very simple library that exposes one variable containing a string. Should be simple I thought, but can't seem to get it to work.
My webpack.config.js:
const path = require('path');
module.exports = {
entry: './src/app.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
library: {
name: 'mypack',
type: 'umd',
},
},
devtool: 'source-map',
devServer: {
watchContentBase: true,
contentBase: path.resolve(__dirname, 'dist'),
port: 9000
},
module: {
rules: [
{
test:/\.css$/,
use:['style-loader', 'css-loader']
}
]
},
}
My package.json:
{
"name": "mypack",
"version": "0.0.1",
"main": "./src/app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"start": "webpack ./src/app.js -d eval --watch --mode development",
"dev": "npx webpack serve"
},
"author": "me",
"license": "ISC",
"devDependencies": {
"css-loader": "^6.0.0",
"webpack": "^5.44.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
},
"dependencies": {
"style-loader": "^3.2.1"
}
}
My src/app.js
let myvar = "test";
export {myvar};
My dist/index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8"><title>test</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="main.js"></script>
</head>
<body>
Test
<script>
console.log(mypack.myvar);
</script>
</body>
</html>
mypack.myvar gives an 'undefined' in the console. mypack seem to be an empty object {}.
How can I access myvar in my package? What am I doing wrong?
Of course, this is only a dummy, in reality I would like to expose objects from the package.
In the end it seems to be a problem with the webppack-dev-server.
If I comment out the line 'contentBase: path.resolve(_dirname, 'dist'),' from the webpack.config.js, copy the index.html to the root of my package and change the script tag source to "dist/index_bundle.js" then it works.
Not sure what is going on there, the script seems to load just fine in the situation above (in the sourceview in the browser, I can click the link and I see the generated javascript) but doesn't seem to be working at all. But that's another question.
I'm trying to output an ESM module with WebPack 5. My understanding is that this feature has been added in version 5, and is used by specifying {output: libraryTarget: 'module'}} and {experiments: {outputModule: true}}.
I believe that what I'm seeing is just a WebPack bug - perhaps related to outputModule still being experimental, but I'm not very well versed in WebPack so could easily have missed something.
I get an error 'return' outside of function. With the configuration below, this happens when I run npx webpack. If I change mode to 'development', then it generates a bundle which indeed has a return statement at the end such that attempting to use it generates a similar error at runtime.
webpack.config.js:
const path = require('path');
module.exports = {
entry: "./index.js",
resolve: { extensions: ['.js'] },
//using 'production' rather than 'development' catches error earlier.
mode: 'production',
experiments: {
outputModule: true
},
output: {
filename: 'hello.js',
libraryTarget: "module",
path: path.resolve(__dirname, 'dist')
}
}
index.js
export default function() { return 42; }
package.json
{
"name": "webpackTest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"webpack": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.5.1",
"webpack-cli": "^4.2.0"
}
}
I am trying to import my WASM library (written in Rust) inside a JS worker. And I get the error:
Uncaught (in promise) TypeError: Failed to resolve module specifier 'mylib'
Or if I try to use worker-loader the error is different, but in the same line:
window is not defined
What is the nature of the errors and how am I supposed to fix it?
The details are represented below. I tried to make the example as minimal as possible (without worker-loader).
The structure of my project is:
wasm-worker-example/
mylib/
pkg/*
src/
lib.rs
Cargo.toml
www/
bundles/*
node_modules/*
index.html
index.js
my.worker.js
package.js
webpack.config.js
lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn concat(a: &str, b: &str) -> String {
a.to_string() + b
}
Cargo.toml
[package]
name = "mylib"
version = "0.1.0"
authors = ["Alexander <mail#fomalhaut.su>"]
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
package.json
{
"name": "www",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"mylib": "file:../mylib/pkg",
"#babel/core": "^7.9.6",
"babel-loader": "^8.1.0",
"webpack": "^4.43.0",
"webpack-bundle-tracker": "^1.0.0-alpha.1",
"webpack-cli": "^3.3.11"
}
}
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const BundleTracker = require('webpack-bundle-tracker');
module.exports = {
mode: 'development',
context: __dirname,
entry: './index',
output: {
path: path.resolve('./bundles/'),
filename: 'app.js',
publicPath: "/bundles/"
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
};
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="bundles/app.js"></script>
</head>
<body>
</body>
</html>
index.js
import("mylib").then(wasm => {
// It works fine
console.log(wasm.concat("qwe", "rty"));
var worker = new Worker("my.worker.js");
worker.postMessage('Message to worker');
});
my.worker.js
// Error: Uncaught (in promise) TypeError: Failed to resolve module specifier 'mylib'
import("mylib").then(wasm => {
// Not reached
console.log(wasm.concat("qwe", "rty"));
self.addEventListener('message', e => {
console.log(e.data);
});
});
I prepare mylib with (in mylib):
wasm-pack build
For frontend (in www):
npm install
./node_modules/.bin/webpack
To run (in www):
http-server