compile single vue component - vue.js

I have created a vue project using vue create myapp. There I have created several components within:
src/components/MyFirst.vue
src/components/MySecond.vue
I have also adjusted my vue.config.js the following way:
module.exports = {
css: {
extract: false,
},
configureWebpack: {
optimization: {
splitChunks: false
},
output: {
filename: '[name].js',
chunkFilename: '[name].js'
}
}
}
So that yarn build creates a single File app.js
Now I would like to use the components I defined there in a static HTML file:
<html lang="de">
<head>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.js"></script>
<script src="/static/app.js"></script>
<title>MyPage<title>
</head>
<body>
<my-comp></my-comp>
</body>
What do I have to do to achieve this?
Is there a way to compile it to one js file per component?

Vue CLI supports a library target, where you can register imported component definitions; or web component target, where components are automatically registered upon import (allowing you to drop in the component like in your example).
Edit the build NPM script in package.json to add the following parameters:
// package.json
{
"scripts": {
"build": "vue-cli-service build --target wc --name my-component src/components/MyComponent.vue"
}
}
The generated dist/demo.html shows example usage:
<script src="https://unpkg.com/vue"></script>
<script src="./my-component.js"></script>
<my-component></my-component>

Related

Vue3 works with unpkg but not with npm + webpack

I'm trying to set up Vue3 so that I can use it via npm + webpack. For some reason the component does not get mounted and no error is shown. If I instead use unpkg it works. How can I make the npm + webpack option work?
I have "vue": "^3.1.5" in my package.json and the following webpack config:
module.exports = {
mode: 'production',
entry: {
provider: './src/components/provider.js',
requester: './src/components/requester.js',
},
optimization: {
minimize: false
},
output: {
path: `${__dirname}/../public`,
filename: '[name].js',
}
}
requester.js:
import { createApp } from 'vue'
createApp({
template: `
<div>
<div>
<h2>Números recibidos</h2>
{{ receivedNumbers }}
<ul>
<li v-for="n in receivedNumbers">{{ n }}</li>
</ul>
</div>
</div>
`,
data() {
return {
receivedNumbers: [1,2,3],
numberRequestIsOpen: false,
}
},
}).mount('#requester-component');
requester.html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>requester</h1>
<div id="requester-component"></div>
<script src="requester.js"></script>
</body>
</html>
resulting html
<h1>requester</h1>
<div id="requester-component" data-v-app=""><!----></div>
<script src="requester.js"></script>
In the other hand, if I add <script src="https://unpkg.com/vue#next"></script> in the head tag of my html and change the js to:
Vue.createApp({
//
}).mount('#requester-component');
then the resulting html is
<h1>requester</h1>
<div id="requester-component" data-v-app=""><div><div><h2>Números recibidos</h2> [
1,
2,
3
] <ul><li>1</li><li>2</li><li>3</li></ul></div></div></div>
<script src="requester.js"></script>
which is the expected output.
Link to the repo in case it helps to play around. Last commit adds the unpkg has, and the previous one has the npm version
https://github.com/vuejs/vue-next/issues/4275
In order to use the functionality of the vue.js template, you need to load the finished package with the compiler and runtime, but vue.js by default loads the runtime only version, so you need to explicitly specify the version (vue.esm-bundler.js)
Adding
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm-bundler.js'
}
}
solved the issue.

How to use min.js in vite2?

such as vue.min.js
I try to external the vue in build.rollupOptions,and import
//vite.config.js
rollupOptions: {
external: ['vue', 'vuetify']
}
// index.html
<script src="/lib/vue.min.js"></script>
<script src="/lib/vuetify.min.js"></script>
and download the vue.min.js and vuetify.min.js ,but it is not work.
the legacy vue.min.js is a umd file but vite need esm version.
so just download the vue.esm.browser.min.js to replace vue.min.js is Ok.
just add external like this:
rollupOptions: {
// 外部化vue 和 vuetify
external: ['vue']
}
and import vue in index.html like this:
...
<head>
...
<title><%= title %></title>
<!-- script -->
<script type="importmap">
{
"imports": {
"vue": "/lib/vue.esm.browser.min.js" //(where the file is)
}
}
</script>
...
</head>
Now you can run vite build in your project, and it works.
But I didnt find esm version of vuetify2.
The net give us some plugins to import external umd which should be pre-handled:
vite-plugin-external
vite-plugin-cdn-import
But i still not make them work,if you have an example successfully,pleace udpate a answer!!!

Why does VS Code fail type acquisition for Vue?

I have a project directory with just three files:
test-proj/
hello.js
index.html
jsconfig.json
Where hello.js looks like this:
const a = jQuery('<div>');
const b = React.Component;
const c = Vue({ el: '#app' });
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Page</title>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="./hello.js"></script>
</body>
</html>
jsconfig.json:
{
"compilerOptions": {
"checkJs": true
}
}
When I open the test-proj directory and open hello.js, VS Code's type checker reports three errors:
Now, I modified jsconfig.json so that VS Code will automatically acquire types for all three:
{
"compilerOptions": {
"checkJs": true
},
"typeAcquisition": {
"include": [
"jquery",
"react",
"vue"
]
}
}
...which makes VS Code recognize that jQuery and React can be used in my script. However, as you see here, it still does not recognize Vue:
TLDR: Why does VS Code fail to acquire type definitions for Vue, when it can do so for React and jQuery?
(Note: This is not a Node.js project. I do not have package.json or node_modules/ under my project directory. I also checked my globally installed npm packages, just to be sure, but I do not have react or jquery installed.)
I examined the Automatic Type Acquisition cache in my PC, which is C:\Users\<username>\AppData\Local\Microsoft\TypeScript\3.8\
The immediate cause seems to be a missing entry in C:\Users\<username>\AppData\Local\Microsoft\TypeScript\3.8\node_modules\types-registry\index.json. It's a ~560KB JSON file which contains the latest version numbers for various NPM packages under the #types scope.
For some reason, this JSON file does not contain an entry for vue, even though the #types/vue package exists on NPM. Strangely enough, it does contain entries for several packages that depend on Vue, such as vue-markdown and vue-ls.
When I added "vue-ls" to my jsconfig.json:
{
"compilerOptions": {
"checkJs": true
},
"typeAcquisition": {
"include": [
"jquery",
"react",
"vue-ls"
]
}
}
...TypeScript downloaded #types/vue-ls into its cache. This pulls in the type definitions in the vue package, which makes the type checks work for Vue.js.

Shoud I load Vue JS manually in laravel?

I have added some Vue Code in a view in a Laravel project. Do I need to include the vuejs in the layout like:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.12/vue.js"></script>
Or laravel takes care of it in someway.
What I have tried:
I ran npm install and npm run dev and I have now app.js and app.css in the public directory.
and I have the following in the view:
const app = new Vue({
el: '#app',
data: {
comments: {},
post: {!! $post->toJson() !!},
user: {!! Auth::check() ? Auth::user()->toJson() : 'null' !!},
comment: 'Your Comment'
},
mounted(){
this.getComments();
},
methods:{
getComments(){
//Some code here
}
}
});
But when I access this view I get:
ReferenceError: Vue is not defined
1- You should add your script in your index file
2- then add that vue codes in the app.js file in the resources\js\app.js
Run npm prod to compile the vue file and add it at the end of the body tag where you want it to use.
How Vue.js is used in laravel
when we run npm install it will download all packages to node_modules directory that are mentioned in the webpack.mix.js.
Then we add required plugins in resources/js/app.js.
In resources/js/app.js we initialize vue.js using
new Vue(
el:'#id_of_the_element'
})
Then we run npm run prod to compile the minified version of vue.js and place it public/js/app.js now it can be added where required
<html>
<body>
<div id="id_of_the_element">
//....
</div>
//import your app.js here
<script src="/js/app.js">
</body>
</html>

Usage webpack with bower

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