I have a project, that when I build the UI, it keeps returning “Module parse failed”.
The problem is VERY similar to this one https://github.com/TypeStrong/ts-loader/issues/867, the only difference is that instead of a static variable, it is the initialization of a variable, like this:
export class AppWebsocket {
client; // WEBPACK SAYS THIS LINE HAS THE ERROR
defaultTimeout;
overrideInstalledAppId;
constructor(client, defaultTimeout, overrideInstalledAppId) {
// Some code
}
}
This problem appears after I am importing something new from a new dependency (the AppWebsocket). The AppWebsocket belongs to a new dependency I’ve installed. And I am importing the AppWebsocket in one of my files.
The problem to this is related to webpack and the rules for the modules according to the link.
On my webpack configuration I have this:
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-react'],
plugins: [],
},
},
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: 'ts-loader',
},
The problem seems to be fixed, if I turn it into this:
{
test: /\.js$/,
use: 'ts-loader',
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: 'ts-loader',
},
The problem is that I don’t understand what are the consequences of this. My project uses react.
I need to solve the webpack problem, but I am not sure what I am doing. Any help to understand or to fix this issue is appreciated.
I have a native addon I am using that works great on my dev machine but fails on any other machine due to the webpack build using an absolute path to the native module instead of a relative one. Here is the error I get:
/main.prod.js:7543: Uncaught Error: Cannot open /Users/.../app/lib/main.node: Error: dlopen(/Users/.../app/lib/main.node, 1): image not found
In my main.dev.js I import the file like this: import main from './lib/main.node';
In webpack config I have added a module test for .node:
export default {
externals: Object.keys(externals || {}),
module: {
rules: [{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
}, {
test: /\.node$/,
use: 'node-loader'
}]
},
...
How can I make sure that my main.node file gets packaged for the build and imported via relative path?
I was able to resolve this issue by switching to a modified version of node-addon-loader. https://github.com/smt116/node-native-ext-loader
Okay, so I have a Typescript definition file model.d.ts. It contains definitions for the classes used in my business logic, so that I can have strong typing in my Vue.js files.
I have a Vue.js template person.vue, with a code section that looks like this:
<script lang="ts">
import axios from "axios";
import * as _ from "lodash";
import * as model from "model";
// ...
</script>
But when I try to build this with Webpack, I run into problems:
ERROR in I:\git\myapp\src\component\person-page\person.vue.ts
[tsl] ERROR in I:\git\myapp\src\component\person-page\person.vue.ts(27,24)
TS2307: Cannot find module 'model'.
ERROR in ../myapp/node_modules/ts-loader!../myapp/node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!../myapp/src/component/person-page/person.vue
Module not found: Error: Can't resolve 'model' in 'I:\git\myapp\src\component\person-page'
# ../myapp/node_modules/ts-loader!../myapp/node_modules/vue-loader/lib/selector.js?type=script&index=0&bustCache!../myapp/src/component/person-page/person.vue 10:14-30
# ../myapp/src/component/person-page/person.vue
# ../myapp/src/main.ts
# multi webpack-hot-middleware/client ./src/main.ts
I'm using ts-loader, and the relevant parts of my webpack.config.js look like this:
module.exports = {
// ...
module: {
rules: [
// ...
{
test: /.ts$/,
use: {
loader: "ts-loader", options: {
appendTsSuffixTo: [/\.vue$/]
}
},
exclude: /node_modules/
},
// ...
{
test: /\.vue$/,
loader: "vue-loader"
}
]
},
resolve: {
extensions: [".ts", ".js", ".vue", ".json"],
alias: {
"vue$": "vue/dist/vue.esm.js"
}
}
};
Why doesn't my definition file work, and how can I make it so that it can be used in person.vue?
I think you have a problem with your path. "model" should point to the complete path to the model.d.ts without the file extensions.
I have font-awesome in my node_modules folder so I try to import it in my main .scss file like so:
#import "../../node_modules/font-awesome/scss/font-awesome.scss";
But Webpack bundling compilation fails, telling me
Error: Cannot resolve 'file' or 'directory' ../fonts/fontawesome-webfont.eot
because the font-awesome.scss file refers to a relative path, '../fonts/'.
How can I tell scss \ webpack to #import another file, and use that file's folder as the home folder so that its relative paths work as it expects?
Use
$fa-font-path: "~font-awesome/fonts";
#import "~font-awesome/scss/font-awesome";
where the $fa-font-path variable is seen in font-awesome/scss/_variables.scss
$fa-font-path: "../fonts" !default;
The tilde "~" is interpolated by sass-loader using the webpack mecanism.
There doesn't appear to be any way to #import files that have their own relative paths in SCSS \ SASS.
So instead I managed to get this to work:
Import the scss \ css font-awesome file in my .js or .jsx files, not my stylesheet files:
import 'font-awesome/scss/font-awesome.scss';
Add this to my webpack.config file:
module:
{
loaders:
[
{test: /\.js?$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ },
{test: /\.jsx?$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ },
{test: /\.scss?$/, loaders: ['style-loader', 'css-loader', 'sass-loader']},
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?mimetype=image/svg+xml'},
{test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
{test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/octet-stream"},
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader"},
]
}
Following worked for me:
$fa-font-path: "~font-awesome/fonts";
#import "~font-awesome/scss/font-awesome";
This is to import the font-awesome & required fonts in the project.
Other change is in webpack configurations, to load required fonts using file-loader.
{
test: /\.scss$/,
loaders: ['style', 'css?sourceMap', 'sass'
],
}, {
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)(\?.*$|$)/,
loader: 'file'
}
This is how it worked for me, the trick is to set $fa-font-path to the path of the fonts as following.
$fa-font-path: "~#fortawesome/fontawesome-free/webfonts/";
#import '~#fortawesome/fontawesome-free/scss/fontawesome.scss';
#import '~#fortawesome/fontawesome-free/scss/solid.scss';
#import '~#fortawesome/fontawesome-free/scss/brands.scss';
Note: Please check your fonts folder in node_modules in my case it is #fortawesome/fontawesome-free
Resolved by changing my app.scss:
#import '~font-awesome/scss/_variables.scss';
$fa-font-path: "~font-awesome/fonts";
#import '~font-awesome/scss/font-awesome.scss';
This way is useful to keep external dependencies unchanged and unversioned.
I just set the path in my main scss file and it works :
$fa-font-path: "../node_modules/font-awesome/fonts";
#import '~font-awesome/scss/font-awesome.scss';
What worked for me was to add resolve-url-loader and enable sourceMaps
I already imported font-awesome in my root .scss file:
#import "~font-awesome/scss/font-awesome";
...
This root file is imported in my main.js file defined as Webpack's entrypoint:
import './scss/main.scss';
...
Then my final webpack module rules look like so:
...
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{ loader: 'postcss-loader', options: { sourceMap: true }, },
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true }, },
],
}, {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: { limit: 1000, name: 'fonts/[name].[ext]', },
}
...
Note:
I used mini-css-extract-plugin, which can be registered like this:
new MiniCssExtractPlugin({
filename: 'css/main.css',
chunkFilename: '[id].[hash]',
}),
url-loader requires file-loader to be installed, so if you get an error like: cannot find module file-loader, then just install it:
npm i -D file-loader
Useful Links:
https://github.com/webpack/webpack/issues/2771#issuecomment-277514138
https://github.com/rails/webpacker/issues/384#issuecomment-301318904
For Version 5.14, the following worked for me:
$fa-font-path : '../node_modules/#fortawesome/fontawesome-free/webfonts';
#import "../node_modules/#fortawesome/fontawesome-free/scss/solid";
#import "../node_modules/#fortawesome/fontawesome-free/scss/brands";
#import "../node_modules/#fortawesome/fontawesome-free/scss/fontawesome";
v.4 (symofony 4 + webpack)
$fa-font-path: "~components-font-awesome/webfonts";
#import '~components-font-awesome/scss/fa-brands';
#import '~components-font-awesome/scss/fa-regular';
#import '~components-font-awesome/scss/fa-solid';
#import '~components-font-awesome/scss/fontawesome';
How to ouput css file as file.css rather than inline in javascript. My configuration look like below.
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader"
}
I tested with
"file-loader!css-loader!less-loader" //but the content of the file is not css
You would have to use the extract-text-plugin. You can create one css file for your entire bundle or one for each chunk. For example if you want all your CSS in your bundle moved to a separate file, you would add this to your figuration
module.exports = {
loaders: [
// Extract css files
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
// Optionally extract less files
// or any other compile-to-css language
{
test: /\.less$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
}
],
plugins: [
new ExtractTextPlugin("[name].css", {
allChunks: true
})
]
}
See stylesheets webpack configuration for more reference