在前面的篇章中,已经说明了 webpack4 的基本使用,那么本章节开始在 webpack4 中构建vue项目,同时对比看看这种构建方式,与在网页script导入 vue.js 中的区别。css
首先从新构建webpack项目。html
package.json 使用存储记录 npm 安装相关包版本便可的。执行如下命令进行初始化:vue
npm init -y
执行以下:node
安装webpack工具至本地项目中:webpack
npm i -D webpack webpack-cli
const path = require('path');
// 这个配置文件,起始就是一个 JS 文件,经过 Node 中的模块操做,向外暴露了一个 配置对象
module.exports = {
// 在配置文件中,须要手动指定 入口 和 出口
entry: path.join(__dirname, './src/main.js'),// 入口,表示,要使用 webpack 打包哪一个文件
output: { // 输出文件相关的配置
path: path.join(__dirname, './dist'), // 指定 打包好的文件,输出到哪一个目录中去
filename: 'bundle.js' // 这是指定 输出的文件的名称
},
};
通常来讲,如今就能够执行 webpack 命令进行打包了,可是我在上面将 webpack 安装到本地项目中,因此还须要编写 npm 执行内部命令的脚本,才可以执行。es6
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
好了,配置了这个以后,就可使用 npm run 脚本名称 来执行了,执行以下:web
npm run build
能够看到已经能够成功编辑打包出 bundle.js 压缩文件了。chrome
首先在main.js 写一个打印信息,以下:npm
console.log("hello world");
而后在index.html引入bundle.js,以下:json
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="../dist/bundle.js"></script>
</body>
</html>
npm i -D babel-loader @babel/core
npm i -D @babel/preset-env @babel/polyfill
npm i -D @babel/plugin-transform-runtime
npm i -S @babel/runtime @babel/runtime-corejs2
注意:使用 -D 也就是 --save-dev,将其安装好测试开发环境, 而 -S 也就是 --save ,将其安装到生产环境的依赖中。
{
"presets": ["@babel/preset-env"],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
注意:"corejs": 2, // 这里设置2是由于上面安装的版本是 @babel/runtime-corejs2
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
]
}
在安装babe将ES6\ES7转化低于语法ES5以前,我先通过测试,发现使用ES6的语法在chrome浏览器是可以支持运行的,而在IE则会报语法错误,以下:
main.js 代码以下:
// ES5
console.log("hello world es5");
// ES6
class Bar {
doStuff() {
console.log('stuff bar');
}
}
var b = new Bar();
b.doStuff(); // "stuff"
// ES6
class Foo {
static classMethod() {
return 'hello static foo';
}
}
console.log(Foo.classMethod()); // 'hello'
执行npm run build打包编译一下,看看 ie浏览器可否识别打印高级语法的信息,以下:
npm i webpack-dev-server -D
在package.json的scripts编写执行命令,以下:
"scripts": {
"dev": "webpack-dev-server"
},
启动执行服务以下:
npm run dev
访问http://localhost:8080/src/
"dev": "webpack-dev-server --open --port 3000 --contentBase src --hot"
-- open : 设置启动服务自动打开浏览器
--port 端口号:配置服务启动端口号
--contentBase src: 启动服务设置index.html的所在目录
--hot:设置采用补丁的方式热更新
前面在配置生成bundle.js的使用时候,已经将其存储在内存中编译生成。那么能不能将index.html页面也加载存储到内存中呢?
这个固然能够,可使用html-wabpack-plugin插件来完成这部分工做。
npm i html-webpack-plugin -D
const path = require('path');
// 导入在内存中生成 HTML 页面的 插件
// 只要是插件,都必定要 放到 plugins 节点中去
// 这个插件的两个做用:
// 1\. 自动在内存中根据指定页面生成一个内存的页面
// 2\. 自动,把打包好的 bundle.js 追加到页面中去
const htmlWebpackPlugin = require('html-webpack-plugin');
// 这个配置文件,起始就是一个 JS 文件,经过 Node 中的模块操做,向外暴露了一个 配置对象
module.exports = {
// 在配置文件中,须要手动指定 入口 和 出口
entry: path.join(__dirname, './src/main.js'),// 入口,表示,要使用 webpack 打包哪一个文件
output: { // 输出文件相关的配置
path: path.join(__dirname, './dist'), // 指定 打包好的文件,输出到哪一个目录中去
filename: 'bundle.js' // 这是指定 输出的文件的名称
},
devServer: { // 这是配置 dev-server 命令参数的第二种形式,相对来讲,这种方式麻烦一些 // --open --port 3000 --contentBase src --hot
open: true, // 自动打开浏览器
port: 3000, // 设置启动时候的运行端口
contentBase: 'src', // 指定托管的根目录
hot: true // 启用热更新
},
plugins: [ // 配置插件的节点
new htmlWebpackPlugin({ // 建立一个 在内存中 生成 HTML 页面的插件
template: path.join(__dirname, './src/index.html'), // 指定 模板页面,未来会根据指定的页面路径,去生成内存中的 页面
filename: 'index.html' // 指定生成的页面的名称
})
],
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
]
}
};
这个插件的两个做用:
npm i style-loader css-loader -D
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, // 配置处理 .css 文件的第三方loader 规则
npm i less-loader less -D
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, //配置处理 .less 文件的第三方 loader 规则
cnpm i sass-loader node-sass -D
cnpm i sass fiber -D
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, // 配置处理 .scss 文件的 第三方 loader 规则
cnpm i url-loader file-loader -D
{ test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=500&name=[hash:8]-[name].[ext]' },
上面这种输入参数的方式还有另外一种方式,以对象的键值对方式,以下:
{
test: /\.(jpg|png|gif|bmp|jpeg)$/,
use: [{
loader: 'url-loader',
options: {
limit: 500, //是把小于500B的文件打成Base64的格式,写入JS
name: '[hash:8]-[name].[ext]' // [hash:8] 在名称前面设置8位哈希值,[name] 设置文件的原名, [ext] 设置文件的原后缀
}
}]
},// 处理 图片路径的 loader
上面已经构建好了webpack的基本使用组件,那么下面能够开始在webpack中开始探讨使用vue的方法。
那么首先来回顾一下普通网页使用script导入vue的过程,以下:
经过这三个步骤,咱们就能够开始 vue 开发了。可是在webpack中也是这样么?
首先在项目本地安装 vue 库先,以下:
cnpm i vue -S
将vue安装到生产依赖中,执行以下:
// 导入vue
import Vue from 'vue'
// 建立vm
var vm = new Vue({
el: '#app',
data: {}
});
「main.js 以下:」
「index.html 渲染数据以下:」
启动服务查看是否正常渲染效果,以下:
vue.runtime.esm.js:620 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
这里提示使用 vue.runtime.esm.js 只会构建运行时的 vue 代码,没法使用模板编译。提示可使用 render 方法返回组件,或者使用内置的编译器构建。
在 webpack 中, 使用 import Vue from 'vue' 导入的 Vue 构造函数,功能不完整,只提供了 runtime-only 的方式,并无提供 像网页中那样的使用方式;
那么若是想要使用网页script直接导入的方式,这时候就须要导入完整的 Vue 功能的js。那么这个完整的 Vue 功能 js 其实就是须要在 nodemodules 里面去查找。
「包的查找规则」:
1.找项目根目录中有没有 「node_modules」 的文件夹
2.在 「node_modules」 中 根据包名,找对应的 「vue」 文件夹
3.在 「vue」 文件夹中,找 一个叫作 「package.json」 的包配置文件
4.在 「package.json」 文件中,查找一个 「main」 属性【main属性指定了这个包在被加载时候的入口文件】
这说明当 import 这个库的时候,则会导入 main属性指定的文件。
若是须要想要完整的功能,应该是要导入完整的 vue.js ,以下:
若是想要修改导入vue的 js,有两种方式,
第一种就是直接在 vue 库的package.json中main中修改引入的文件,
第二种则是 import 的时候直接手写引入的文件路径。
将原来引入的代码
"main": "dist/vue.runtime.common.js",
"module": "dist/vue.runtime.esm.js",
改成
"main": "dist/vue.min.js",
"module": "dist/vue.min.js",
此时,再来编译服务,能够看到浏览器正常渲染数据了。
可是通常来讲,咱们不会修改库的文件方式。下面来看看第二种,再次以前将库文件的main属性改回去。
此时查看编译后可否查看渲染数据,以下:
能够看到也能够正常如同网页 script 引入同样渲染数据了。
可是若是将导入vue写成这样路径写法:
import Vue from '../node_modules/vue/dist/vue.min.js'
看上去很是不优雅,可否依然是写成
import Vue from 'vue'
可是又不修改vue库的main属性,又能够导入实际vue.min.js完整功能的脚本呢?
此时就要使用resolve属性来设置导入库别名 alias 了。
首先将导入包的方式改回去,以下:
在webpack.config.js添加resolve属性,以下:
resolve: {
alias: {
'vue$': 'vue/dist/vue.min.js'
}
}
再次编译运行服务,确认是否模板渲染正常,能够发现也是能够正常渲染的。
从上面的过程当中能够发现webpack默认导入vue的话,导入的是run-time-only的非完整js,而咱们在普通网页中使用的,通常导入完整的vue库文件。
若是须要修改使用模板渲染的功能,那么只能修改一下vue导入的文件了。
那么是否存在我依然使用run-time-only的vue库,依然能够将组件渲染到 app容器的方式呢?
这个固然有,就是使用render函数。
为了演示效果,咱们先将上面设置的alias注释,改回使用run-time-only库。
下面来建立一个login组件,而后将其渲染到容器中。
// 建立login组件
var login = {
template: "<h1>这是login组件。</h1>"
};
main.js 中注册组件login
index.html 中使用组件login
启动服务,查看可否正常显示,以下:
在上面的示例看到,使用run-time-only 的 vue,没法使用模板直接在 vm 中渲染组件。那么下面咱们抽离 login 组件出来到 login.vue 文件中,而后使用 render 来返回渲染 login 组件。看看效果。
<template>
<div>
<h1>这是login登陆组件</h1>
</div>
</template>
<script>
</script>
<style>
</style>
能够看到 vue 文件主要分为了三部分:template 、script、 style
那么下面先来看看若是直接看成组件导入会是什么效果。
那么下面启动服务,看看页面,以下:
默认webpack是没法编译vue文件的,须要安装相关的插件。
「安装命令:」
npm i vue-loader vue-template-compiler -D
npm i vue-loader-plugin -S
执行以下:
「在webpack.config.js中,添加以下module规则:」
{ test: /\.vue$/, use: 'vue-loader' }, // 配置处理 .vue 文件
「还要配置插件:」
// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
// ...
plugins: [
new VueLoaderPlugin()
]
}
再次编译,此时已经没有报错了,页面只是提示runtime-only的告警信息,以下:
// 使用render函数渲染组件
render: function (createElements) {
return createElements(login)
}
此时网页看看是否成功渲染组件,以下:
能够看到已经成功渲染组件了。
下面简写一下render函数,以下:
// 使用render函数渲染组件
render: c => c(login)
总结梳理:webpack 中如何使用 vue :
1.安装vue的包:cnpm i vue -S
2.因为 在 webpack 中,推荐使用 .vue 这个组件模板文件定义组件,因此,须要安装 能解析这种文件的
npm i vue-loader vue-template-compiler -D
npm i vue-loader-plugin -S
「更多精彩原创Devops文章,快来关注个人公众号:【Devops社群】 吧:」
点击下面,查看更多Vue系列文章