Usage webpack with bower - npm

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

Related

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!!!

How to use Vue Testing Library with Nuxt.js?

I want to use Vue Testing Library in my Nuxt.js app. But straight after installing the package, launching a test triggers this error:
'vue-cli-service' is not recognized as an internal or external
command, operable program or batch file.
This is presumably because Nuxt.js does not use vue-cli-service.
Despite that, is there a simple way to use Vue Testing Library with Nuxt.js?
It sounds like you might have an NPM script that includes vue-cli-service (as shown below), but that's intended for Vue CLI scaffolded projects:
{
"scripts": {
"test:unit": "vue-cli-service test:unit" ❌ not for Nuxt projects
}
}
However, you could setup Vue Testing Library using one of the methods outlined below.
Setup on new project
When generating a new Nuxt project, select Jest for testing, and install Vue Testing Library on top of that:
Scaffold a Nuxt project with create-nuxt-app, and select Jest at the Testing framework prompt:
npx create-nuxt-app nuxt-testing-library-demo
Sample output:
$ npx create-nuxt-app nuxt-testing-library-demo
create-nuxt-app v3.5.2
✨ Generating Nuxt.js project in nuxt-testing-library-demo
[...]
? Testing framework: Jest
Install Vue Testing Library (v5 required for Nuxt 2):
npm install -D #testing-library/vue#5
Run tests with the test NPM script (scaffolded from step 1):
npm run test
Setup on existing Nuxt project
For an already existing Nuxt project that has no testing framework, mimic the jest template from #nuxt/create-nuxt-app to add Vue Testing Library support:
Install the prerequisite NPM packages:
npm install -D #testing-library/vue#5 \
vue-jest#^3 \
jest#^26 \
babel-core#7.0.0-bridge.0 \
babel-jest#^26
npm install -D ts-jest#^26 # if using TypeScript
For Nuxt v2, install #testing-library/vue#5.
Add an NPM script to run Jest CLI:
// <rootDir>/package.json
{
"scripts": {
"test": "jest"
}
}
Add a Jest config:
// <rootDir>/jest.config.js
module.exports = {
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/$1',
'^~/(.*)$': '<rootDir>/$1',
'^vue$': 'vue/dist/vue.common.js'
},
moduleFileExtensions: [
'ts', // if using TypeScript
'js',
'vue',
'json'
],
transform: {
"^.+\\.ts$": "ts-jest", // if using TypeScript
'^.+\\.js$': 'babel-jest',
'.*\\.(vue)$': 'vue-jest'
},
collectCoverage: true,
collectCoverageFrom: [
'<rootDir>/components/**/*.vue',
'<rootDir>/pages/**/*.vue'
]
}
Add a Babel config:
// <rootDir>/.babelrc
{
"env": {
"test": {
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
}
}
Create a test directory, containing the example test file shown below (taken from Vue Testing Library example). Note the location of the test files can be configured with the testMatch or testRegex setting in jest.config.js.
Example component:
<!-- <rootDir>/components/Counter.vue -->
<template>
<div>
<p>Times clicked: {{ count }}</p>
<button #click="increment">increment</button>
</div>
</template>
<script>
export default {
data: () => ({
count: 0,
}),
methods: {
increment() {
this.count++
},
},
}
</script>
Example test:
// <rootDir>/test/Counter.spec.js
import {render, screen, fireEvent} from '#testing-library/vue'
import Counter from '#/components/Counter.vue'
test('increments value on click', async () => {
render(Counter)
expect(screen.queryByText('Times clicked: 0')).toBeTruthy()
const button = screen.getByText('increment')
await fireEvent.click(button)
await fireEvent.click(button)
expect(screen.queryByText('Times clicked: 2')).toBeTruthy()
})
Run tests with the test NPM script (added in step 2):
npm run test
GitHub demo

compile single vue component

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>

How to load a css file in generated index.html file?

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

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.