My problem :
Path generated for images are the same for images used in css or in a vue component.
Images are correctly loaded from CSS files, but are not found when declared in a vue component.
Version of webpack : 3.6.0
Here is the webpack configuration
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
publicPath: '../../',
limit: 1000,
name: utils.assetsPath('images/[name].[hash:7].[ext]')
}
},
{
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
name: utils.assetsPath('css/[name].[ext]'),
}
},
]
}
sourceMap is enabled and publicPath is './'
All works correctly if files are deployed in server root directory, but it is deployed in a subdirectory, it doesn't.
Let's say I deploy my files in a 'dev' subdirectory.
Images in CSS files will be search in /dev/static/images/
Images in vue components will be searched in /static/images/, where they won't be found...
I can't figure out what I am doing wrong... Any help or advice is appreciated.
Thanks !
Related
I'm struggling with the Setting up Loaders for my VueJS project (vue3), to be more specific i have a following structure of the folders
My Images is located at path called assets and I would like url-loader to know, that he need to grab images from THIS path.
my loaders configuration at vue.config.js looks following
configureWebpack: {
module: {
rules: [
{ test: /\.(jpg|jpeg|png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader',
options: {limits: 100000, name: "/assets/[name].[ext]"}},
],
}
},
If there is any obvious mistakes PLEASE point out on them.
Cuz i'm not really sure if i did it right
I want to embed a react-native-web application into an existing website and am currently looking for options how to do so.
The application should be a quite simple questionnaire which needs to be embedded into a website created with Elementor. My idea was to use the Elementor HTML widget and insert my application somehow, but unfortunately I cannot figure out how to do this.
I've got a bit of experience developing React Native(RN) apps but I am pretty new to web development and therefore thought it would be easier for me to go with RN and the react-native-web library.
So far, I've created a RN project using npx react-native init WebApp, copied the App.js, index.js and package.json files from react-native-web CodeSandbox template, deleted the node_modules folders and ran npm install. Then I was able to start and build this example web app with the scripts from the package.json.
Now my question, how can I use the output from the build directory and embed it into an html tag?
I also tried to use webpack with the configuration from the react-native-web docs to bundle the app but I always got a new error as soon as I fixed the last one. Is it possible to bundle a RN app into a single JS file which I could then insert into the website?
Looking forward to any advice!
Marco
I solved it by using the below webpack config. The created bundle.web.js' content is put into a script tag (<script>...</script>). This can be embedded into the HTML widget.
// web/webpack.config.js
const path = require('path');
const webpack = require('webpack');
const appDirectory = path.resolve(__dirname, '');
// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfiguration = {
test: /\.js$/,
// Add every directory that needs to be compiled by Babel during the build.
include: [
path.resolve(appDirectory, 'index.web.js'),
path.resolve(appDirectory, 'src'),
path.resolve(appDirectory, 'node_modules/react-native-uncompiled'),
],
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
// The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
presets: ['module:metro-react-native-babel-preset'],
// Re-write paths to import only the modules needed by the app
plugins: ['react-native-web'],
},
},
};
// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
},
},
};
module.exports = {
entry: [
// load any web API polyfills
// path.resolve(appDirectory, 'polyfills-web.js'),
// your web-specific entry file
path.resolve(appDirectory, 'src/index.js'),
],
// configures where the build ends up
output: {
filename: 'bundle.web.js',
path: path.resolve(appDirectory, 'dist'),
},
// ...the rest of your config
module: {
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
},
resolve: {
// This will only alias the exact import "react-native"
alias: {
'react-native$': 'react-native-web',
},
// If you're working on a multi-platform React Native app, web-specific
// module implementations should be written in files using the extension
// `.web.js`.
extensions: ['.web.js', '.js'],
},
};
How do I add a cdn path variable into the styles.scss before compilation? I have a webpack 4 configuration that works fine for JS. The JS/CSS files are loaded correctly from the desired cdn url.
What I want to achieve is, that the project running on localhost will use a different cdn url for images/icons/fonts than the same web running on production.
My webpack config has these lines for setting the cdn domain:
if (process.env.NODE_ENV === 'production') {
webUrl = 'https://cdn.project.com/';
}
else if (process.env.NODE_ENV === 'development') {
webUrl = 'http://localcdn.localhost/';
}
This code works well for JS/CSS files, but CSS always loads backgrounds/fonts using a relative path, which of course is the main domain and not the cdn.
Maybe just open the styles.scss and update the file manually before webpack compilation? Isn't there a better way?
After hours of trial and error I found this solution for webpack 4. It may help someone trying to solve the same issue.
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options : {
url : false,
sourceMap: devMode
}
},
{
loader: 'sass-loader',
options : {
processCssUrls : false,
sourceMap: devMode,
data : "$cdnFolder: 'http://cdn.myweb.net/';"
}
}
],
},
This is a part of webpack.config.js, in the section:
module : {
rules : {
This configuration makes the scss variable $cdnFolder available in every scss file. CDN link can be changed based on the current mode dev/prod/stage.
For webpack 5, the config changed a little:
{
loader: 'sass-loader',
options : {
additionalData : "$cdnFolder: '" + cdnUrl + "';"
}
}
I have successfully used the webfonts-loader package to generate a font and class-definitions for icons, but it isn't served by my nuxt dev server. There is a styletag in my head with:
#font-face {
font-family: "TopLoggerIcons";
src: url("/myfont.eot?#iefix") format("embedded-opentype"), url("/myfont.woff2") format("woff2");
}
But the requested http://localhost:3010/myfont.woff2 gives a 404. I had this working in the nuxt version before 2.0 (and before webpack 4), where the file is served from http://localhost:3010/_nuxt/myfont.woff2. The font is currently also served from there, but the path in the font-face declaration is wrong. I'm wondering what has changed here removing the (required?) _nuxt part in the path.
In my nuxt.config.js file I have:
build: {
extend(config, ctx) {
config.module.rules.push({
test: /plugins\/icons\.js$/,
use: ['vue-style-loader', 'css-loader', 'webfonts-loader'],
})
},
}
Now according to the example on the webfonts-loader lib I need to use the MiniCssExtractPlugin.loader instead of the vue-style-loader, but that doesn't work. I read here that it is internally used by nuxt, but i don't know how to add it here.
Hope anyone has an idea where to look...
Ok, just figured it out: you have to use the publicPath option of the webfonts-loader package:
extend(config, ctx) {
config.module.rules.push({
test: /plugins\/icons\.js$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'webfonts-loader',
options: {
publicPath: config.output.publicPath,
},
}
],
})
}
The config.output.publicPath is /_nuxt/.
I use some npm packages in my project. Two of them have the wrong main-field. Is it possible to override them?
I use webpack. I found a solution here.
This works for the main field but I also need a css-file from the same package. I refer it with ~package/css/style.css in my index.scss file. With the solution above it resolves the path with path/to/main.js/css/style.css (with main.js) instead of path/to/css/style.css (without main.js).
I could refer it directly ../node_modules/path/to/css/style.css but I think thats ugly.
So is there an other solution with webpack or npm to override this main field?
-- EDIT --
I use bootstrap-treeview as package. I refer it in index.scss like so
#import '~bootstrap-treeview/src/css/bootstrap-treeview.css';. This works.
When I add 'bootstrap-treeview': path.join(_path, 'node_modules', 'bootstrap-treeview', 'src', 'js', 'bootstrap-treeview.js') as alias in webpack import 'bootstrap-treeview'; works but the css not (as describes above).
-- EDIT 2 --
webpack.conf.js:
resolve: {
extensions: ['', '.js'],
modulesDirectories: ['node_modules'],
alias: {
// bootstrap-treeview alias
'bootstrap-treeview': path.join(_path, 'node_modules', 'bootstrap-treeview', 'src', 'js', 'bootstrap-treeview.js')
}
},
module: {
loaders: [
{
test: /\.css$/,
loaders: [
'style-loader',
'css-loader?sourceMap',
'postcss-loader'
]
},
{
test: /\.(scss|sass)$/,
loader: 'style-loader!css-loader?sourceMap!postcss-loader!sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true
}
]
}
index.scss see above.
Error with bootstrap-treeview alias:
Module not found: Error: Cannot resolve 'file' or 'directory' /home/ekf/develop/generator-angular-webpack/node_modules/bootstrap-treeview/src/js/bootstrap-treeview.js/src/css/bootstrap-treeview.css in ...
Error without alias:
Module not found: Error: Cannot resolve module 'bootstrap-treeview' in ...
just in case
webpack scss loader config
module: {
loaders: [
{
test: /\.css$/,
exclude: /node_modules/,
loader: "style-loader!css-loader"
},
{
test: /\.scss$/,
exclude: /node_modules/,
loader: "style-loader!css-loader!sass-loader"
}
]
}
The problem is that your alias points directly to the JS file, instead of pointing to the common ancestor of both the JS and the CSS. It's nice and convenient to be able to import Treeview from "bootstrap-treeview" but it leads to the problem you're describing.
Instead, you could specify a higher level alias:
resolve: {
alias: {
// bootstrap-treeview alias
'bootstrap-treeview': path.join(_path, 'node_modules', 'bootstrap-treeview', 'src')
}
},
and get the JS as import Treeview from "boostrap-treeview/js/bootstrap-treeview.js". This allows you to get the CSS as require("bootstrap-treeview/css/bootstrap-treeview.css").
You might be able to get clever about it and tell Webpack to look for CSS files in ~/css/ and JS files in ~/js/ but that would be adding more magic for (IMHO) little gain.