Created a vue project using vue create . command. I am generating my own index.html file using the following configs:
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
}),
Now in index.html how I can link a css file? I tried like this but its not working
<link rel="stylesheet" href="~#/assets/custom/styles.css">
How to load the correct path in href?
you need to setup entry javascript file like that
config.entry = {
mainJs: 'main.js'
}
and import your root css file to that js.
import '../css/main.scss';
webpack will recognize that css and will inject into resulting html. you need to configure css loader in config.rules as well
config.module = {
rules: [
...
{
test: /\.css$/,
use: [
DEV ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
],
}
]
say him 'inject: body'
new HtmlWebpackPlugin({
inject: 'body'
that will lead to js being injected into body, and css will remain in head
Related
I am using the Vue ESLint plugin and it has a rule for not allowing single word component names.
However, I am also using Nuxt, and to set a default Layout in Nuxt you need a .vue component named default.vue which throws the ES Lint rule errors.
I can't seem to get it to just disable in that one .vue file that is actually pretty small...
<template>
<div>
<Header/>
<Nuxt/>
</div>
</template>
But if I disable the rule in my .eslintrc.js then it works.
module.exports = {
root: true,
env: {
browser: true,
node: true,
},
extends: [
'#nuxtjs/eslint-config-typescript',
'plugin:nuxt/recommended',
'prettier',
],
plugins: [],
// add your custom rules here
rules: {
'vue/multi-word-component-names': 'off',
},
}
Is there a way to disable the rule for just one Vue file?
In your case, you can replace
'vue/multi-word-component-names': 'off'
with:
'vue/multi-word-component-names': ['error', {
'ignores': ['default']
}]
this will set the rule to 'allow' for all files named 'default'
you can read more about it here: https://eslint.vuejs.org/rules/multi-word-component-names.html
rules: { 'vue/multi-word-component-names': 0 }
try this way
Go to package.json and in the eslintConfig object add the following rule: "vue/multi-word-component-names": "off"
or even better:
"vue/multi-word-component-names": 0
Like so:
You should have eslintConfig in package.json.
You need just set vue/multi-word-component-names to 0
rules: {
'vue/multi-word-component-names': 0
}
Just the below line the vue.config.js file:
module.exports = defineConfig({
....
lintOnSave: false
})
Go to the vue.config.js file
Add lintOnSave:false to the file.
You can replace vue.config.js
with:
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave: false,
})
Run Command npm install standardx --global.
In vue.config.js, add lintOnSave:false.
In App.vue inside template, add div as parent element and wrap your image and component that you are using in that.
this is my first question here so please let me know if you need more info.
I am working on a small project using vue CLI 3 and I want to add audio and audio controls but I get the following error:
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
I don't really know how to edit webpack. Nonetheless, I found this in the documentation to create a vue.config.js file. But I don't really understand what should I add there.
this is how my component looks:
<template>
<div class="controller-container">
<audio controls>
<source src="#/assets/Catastrophe03music.m4a" type="audio/mp4" />
</audio>
</div>
</template>
<script>
export default {
name: "MusicController",
components: {},
};
</script>
thanks for helping
If you are using Vue App then go to webpack.config.js and add the following code
module: {
rules: [
{
test: /\.mp3$/,
loader: 'file-loader',
exclude: /node_modules(?!\/foundation-sites)|bower_components/,
options: {
name: '[path][name].[ext]'
}
}
]
}
But if you have webpack.mix.js file then add the following code.
mix.webpackConfig({
module: {
rules: [
{
test: /\.mp3$/,
loader: 'file-loader',
exclude: /node_modules(?!\/foundation-sites)|bower_components/,
options: {
name: '[path][name].[ext]'
}
}
]
}
});
I've recently switched to Webpack and have all my JS and CSS running perfectly through it now. Here's the relevant piece of webpack.config.js:
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
},
{loader: 'import-glob-loader'}
]
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
{loader: MiniCssExtractPlugin.loader},
{loader: 'css-loader'},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')
]
}
},
{loader: 'sass-loader'},
{loader: 'import-glob-loader'}
]
}
]
I have Vue included from a CDN and with this setup I can do the following no problem:
Vue.component('test-component', {
data: function () {
return {
title: 'Title',
description: 'Description'
};
},
methods: {
created: function () {
console.log('Created');
}
},
template: '<section id="test-component"><h2>{{ title }}</h2>{{ description }}</section>'
});
new Vue({el: '#app'});
And in my HTML:
<div id="app">
<test-component></test-component>
</div>
I'd now like to use Vue single file components instead, and reading the docs it tells me to simply run .vue files through vue-loader, so I changed my rules to the following:
rules: [
// NOTE: This is new
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
},
{loader: 'import-glob-loader'}
]
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
{loader: MiniCssExtractPlugin.loader},
{loader: 'css-loader'},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')
]
}
},
// NOTE: This is new too, but commented because it throws errors
// {loader: 'vue-style-loader'},
{loader: 'sass-loader'},
{loader: 'import-glob-loader'}
]
}
]
With that in place my .vue files are picked up and added to dist/main.js so it seems to be working (as long as I don't include a <style> element in the Vue file in which case it fails), but now new Vue({el: '#app'}) does absolutely nothing. Checking the DOM the <test-component> is still in there and not rendered by Vue at all.
If I also try to enable vue-style-loader the build fails entirely saying:
(1:4) Unknown word
> 1 | // style-loader: Adds some css to the DOM by adding a <style> tag
| ^
2 |
3 | // load the styles
What am I doing wrong here?
Edit: Progress. Thanks to Daniel my <style> now works as long as it has lang="scss" set. This is because my webpack config only has rules for scss files and not css files.
I've also figured out the reason the <test-component> won't render is because I never actually register it, simply including the .vue-file is not enough for it to be registered obviously.
The problem I'm having now is trying to glob import all my .vue-files as an array of components. If I do this it works fine:
import TestComponent from "./test-component.vue";
import AnotherComponent from "./another-component.vue";
document.querySelectorAll('[data-vue]').forEach(el => {
new Vue({
el: el,
components: {
'test-component': TestComponent,
'another-component': AnotherComponent
}
});
});
But I'd like to be able to do this some how:
import components from "./**/*.vue";
document.querySelectorAll('[data-vue]').forEach(el => {
new Vue({
el: el,
components: components
});
});
Using import-glob-loader.
Simply importing the vue files is not enough for them to be available for use. You also have to register them with Vue.
So, this is wrong:
import 'component.vue';
new Vue({el: '#app'});
This is right:
import component from 'component.vue';
new Vue({
el: '#app',
components: {
'component': component
}
});
That takes care of making them usable.
The reason the <style> elements don't work is because I don't have a webpack rule for CSS files - only for SCSS files. Thanks to #Daniel for pointing out that I need <style lang="scss">.
vue-style-loader is only needed to inject styles into the DOM as <style> elements which I don't actually use (I use mini-css-extract-plugin to create css-files) also according to the docs:
However, since this is included as a dependency and used by default in vue-loader, in most cases you don't need to configure this loader yourself.
Will create a separate question regarding the glob import.
Make sure you have <style lang="scss"> in your SFC
You can also try deleting the package-lock and node_modules folder and do a clean install. Sometimes that can resolve an issue if the dependencies are not using compatible versions.
Update
To import using glob style imports you may need to use import-glob
https://www.npmjs.com/package/import-glob
You can also achieve similar result using global component registration. This is documented well in the official docs at:
https://v2.vuejs.org/v2/guide/components-registration.html#Automatic-Global-Registration-of-Base-Components
When using Webpack is pretty straight forward to add an alias for scss files in a Vue SFC, e.g:
<style lang="scss">
#import "~scss/config/config";
...
</style>
Would be the following in Webpack:
alias: {
sass: path.resolve(__dirname, '../scss/')
}
How would you add the same kind of alias in Rollup via rollup-plugin-vue?
I've tried adding a number of postcss plugins, e.g
import importer from 'postcss-import';
vue({
css: false,
style: {
postcssPlugins: [
importer({
path: null,
addModulesDirectories: [path.resolve(__dirname, '../shared')]
})
]
}
}),
I've also tried: rollup-plugin-alias, rollup-plugin-includepaths and some other postcss plugins.
I don't think you can use postcss plugins within the Vue plugin to accomplish this, because it compiles the scss before it gets passed to postcss.
Using rollup-vue-plugin I've been able to use style.preprocessOptions.scss.includePaths to alias directories, in my case pointing to node_modules:
//rollup.config.js
import VuePlugin from 'rollup-plugin-vue'
...
plugins: [
VuePlugin({
style: {
preprocessOptions: {
scss: {
includePaths: ['node_modules'],
}
}
})
]
...
// some .vue file
<style>
#import 'some-node-module' //resolves to 'node_modules/some-node-module'
</style
I have a basic ReactJS application. I use webpack and would like to use moduls from bower. I installed bower-webpack-plugin and add jquery library in bower.
webpack.config.js
var BowerWebpackPlugin = require("bower-webpack-plugin");
var webpack = require("webpack");
module.exports = {
entry: './index.jsx',
output: {
filename: 'bundle.js',
publicPath: 'http://localhost:8090/assets'
},
module: {
loaders: [
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony'
}
]
},
plugins: [
new BowerWebpackPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
})
],
externals: {
//don't bundle the 'react' npm package with our bundle.js
//but get it from a global 'React' variable
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
jquery: "./bower_components/jquery/dist/jquery.js"
}
}
}
Edit: Now I am using this webpack config with bower dependencies and without bower-webpack-plugin
bower.json
{
"name": "jquery",
"version": "2.1.4",
"main": "dist/jquery.js",
"license": "MIT",
"ignore": [
"**/.*",
"build",
"dist/cdn",
"speed",
"test",
"*.md",
"AUTHORS.txt",
"Gruntfile.js",
"package.json"
],
"devDependencies": {
"sizzle": "2.1.1-jquery.2.1.2",
"requirejs": "2.1.10",
"qunit": "1.14.0",
"sinon": "1.8.1"
},
"keywords": [
"jquery",
"javascript",
"library"
]
}
index.html
<!DOCTYPE html>
<html>
<head>
<title>Basic Property Grid</title>
<!-- include react -->
<script src="./node_modules/react/dist/react-with-addons.js"></script>
</head>
<body>
<div id="content">
<!-- this is where the root react component will get rendered -->
</div>
<!-- include the webpack-dev-server script so our scripts get reloaded when we make a change -->
<!-- we'll run the webpack dev server on port 8090, so make sure it is correct -->
<script src="http://localhost:8090/webpack-dev-server.js"></script>
<!-- include the bundle that contains all our scripts, produced by webpack -->
<!-- the bundle is served by the webpack-dev-server, so serve it also from localhost:8090 -->
<script type="text/javascript" src="http://localhost:8090/assets/bundle.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("body").append("This is Hello World by JQuery");
});
</script>
</body>
</html>
When I open main page, I get error message: "$ is not defined".
project structure
First, maybe you just forgot, but to be sure, I want to point out that it seems you showed us the jquery bower.json file in your question.
Your project doesn't actually seem to have a bower.json file at its root.
If you want to use Bower to manage dependencies, make sure you have a bower.json by running bower init at the root of your project and then run for instance bower install --save jquery.
See the bower doc for more info ;)
Besides that, the problem is that you're trying to use jQuery in index.html, so not in a webpack-managed module.
Webpack is not actually processing anything on your index.html.
What I mean is, put your jQuery code in index.jsx, instead of putting it in index.html:
// index.jsx
$(document).ready(function(){
$("body").append("This is Hello World by JQuery");
});
And it should work!
You can also remove this code, since the BowerWebpackPlugin handles that for you:
alias: {
jquery: "./bower_components/jquery/dist/jquery.js"
}
How does it work?
index.jsx is loaded through Webpack.
$ is used as a free variable, but thanks to the ProvidePlugin, it will resolve to require("jquery")
require("jquery") resolves to import jQuery from the bower components folder
thanks to the BowerWepackPlugin.
Without the ProvidePlugin and only the BowerWebpackPlugin, you would have had to write:
// index.jsx
var $ = require("jquery");
$(document).ready(function(){
$("body").append("This is Hello World by JQuery");
});
add a resolve field:
resolve: {
alias: {
jquery:"/your/path/to/jquery"
}
}
and add this to your plugin:
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
})
]
hope it helped