什么是 webpack
是前端的一个项目构建工具,他是基于 Node.js 开发出来的一个前端工具
如何完美实现上述的两种解决方案
- 使用 Gulp 基于流的自动化构建工具,小巧灵活,适合功能点的开发
- 使用 Webpack 适合与整个项目的构建
webpack 安装的两种方式
- 运行
npm i webpack -g
全局安装 webpack,这样就能在全局中使用 webpack 的命令 - 在项目根目录中运行
npm i webpack --save-dev
安装到项目依赖中
配置
1.现在先要装 JQuery
npm init -y
// 用来初始化生成一个新的package.json
文件。会问很多配置修改问题,如果不改,一路回车。-y
(yes
)表示跳过提问阶段-
npm i jquery -s
//install
命令可以使用不同参数,指定所安装的模块属于哪一种性质的依赖关系,即出现在packages.json
文件的哪一项当中。-s
(-save
)模块名被添加到dependencies
2.导包时候的问题
我们不要在<head>
标签中导入任何包和CSS
,会拖慢渲染速度,应该在main.js
当中加载 webpack .\src\main.js .\dist\bundle.js
:webpack
处理main.js
生成bundle.js
(一个浏览器能够正常解析执行的js
文件)
我们在main.js
中import $ from 'jquery';
和const = require('jquery')
都不行,所以,现在想要利用webpack
解决这个问题:
webpack
能够做什么事情?
正常的 js 文件不能引用其他的 js 文件
- webpack 能够处理 JS 文件的互相依赖关系
- webpack 能够处理 JS 的兼容问题,将高级的浏览器所不能识别的语法,转换为浏览器所能识别的语法
修改代码 main.js
以后怎么办?
重新输正常代码打包很麻烦,所以我们配置 webpack 的配置文件:
- 在项目的根目录创建文件
webpack.config.js
- 在该文件中像这样配置
/* jshint esversion: 6 */
// 这个配置文件,其实就是一个 JS 文件,通过 Node 中的模块操作,向外暴露了一个配置对象
const path = require("path");
module.exports = {
// 手动指定入口和出口
entry: path.join(__dirname, "./src/main.js"), // 表示要使用 webpack 打包哪个文件
output: {
path: path.join(__dirname, "./dist"), // 指定打包好的文件,输出到哪个目录中
filename: "bundle.js" // 指定输出的文件名称
}
};
配置以后
webpack
命令发生了什么?
- 首先, webpack 发现我们并没有指定入口和出口,他就会去项目的根目录去查找是否有
webpack.config.js
配置文件- 当找到配置文件后,解析执行该文件,当解析执行文件后,就得到了配置中所导出的配置对象后,就拿到了 配置对象中指定的入口和出料口,然后进行打包构建
现在的话每次改动后输入 webpack
即可打包,但是就算这样每次也都要改,很麻烦
- 使用
webpack-dev-server
这个工具,来实现自动打包编译的功能
- 运行
npm i webpack-dev-server -D
(模块名将被添加到devDependencies
),安装这个工具到项目的本地开发依赖 - 安装完毕后,这个工具的用法和
webpack
的使用方法完全一样 - 由于是在项目中本地安装的这个工具,所以无法把它当做脚本命令在
powershell
终端中直接运行(只有那些全局安装的才能在终端中正常执行) - 注意
webpack-dev-server
如果想要正常运行,要求,在本地项目中,必须安装webpack
- 注意,即使是全局安装了
webpack
我们也要将它们安装进项目依赖当中 - 页面中的 (利用
webpack
生成的)bundle.js
放置在我们的 dist 文件夹中,但是webpack-dev-server
生成的 bundle.js 托管在我们电脑的内存中(并没有存放在实际的物理磁盘上),所以要注意我们引用的 bundle.js 在项目的根目录/bundle.js
(是找不到的)[ 放在内存中比较快嘛 ] - --hot 可以实现浏览器的无刷新重载,异步刷新
- 即使这样配置
contentBase
指令的过程也很麻烦,需要指定启动的目录,而且还要修改index.html
和script
标签的src
属性,所以推荐使用html-webpack-plugin
插件配置启动页面
- 运行
npm i html-webpack-plugin --save-dev
安装到以来开发 - 修改 webpack.config.js 配置文件:
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 手动指定入口和出口
entry: path.join(__dirname, "./src/main.js"), // 表示要使用 webpack 打包哪个文件
output: {
path: path.join(__dirname, "./dist"), // 指定打包好的文件,输出到哪个目录中
filename: "bundle.js" // 指定输出的文件名称
},
plugins: [
// 配置插件的节点
// 3
new webpack.HotModuleReplacementPlugin(), // new 一个热更新的模块对象
new htmlWebpackPlugin({
// 创建一个内存中生成 html 的插件
template: path.join(__dirname, "./src/index.html"), //会根据指定的模板页面,生成的内存中页面’
filename: "index.html"
})
]
};
这个插件的两个功能 1.自动在内存中模板指定页面生成一个内存中的页面 2.自动把打包好的 bundle.js 追加到页面中去
webpack
打包 css
文件
-
webpack
只能打包JS
类型的文件,如果想要打包非 JS 类型的文件需要安装,npm i css-loader style-loader -D
- 打开 webpack.config.js 新增一个配置节点,叫做 module(一个对象),在对象上,有个 rules 属性,是个数组;这个数组中存放了所有第三方文件的匹配和处理规则。
- 如图
module: {
// 这个节点用于配置所有的第三方模块加载器
// 规则 --- css
rules: [
// 配置处理 .css 文件的第三方 loader 模块,调用顺序从右到左
{ test: /\.css$/, use: ["style-loader", "css-loader"] }
];
}
webpack
无法处理 URL
,解决方法和上面一样
注:一些依赖关系,忘了也没关系,这几个都是内部依赖,不需要写到 webpack.config.js
当中
- less-loader ---> less
- url-loader ---> file-loader
- sass-loader ---> node-sass
如何配置使得图片不会转成 base64
(为什么? --> 我在提问)
在 url-loader 的配置中添加一句
{ test: /\.(jpg|png|gif|jpeg)$/, use: 'url-loader?limit=200,000'}
limit 给定的值是图片的大小,单位是比特,如果我们引用的图片大于或者等于给定 limit 的值就不会转为 base64 格式的字符串。
Q 为什么图片的名字会被改掉
A 防止重名,url 中的 '/' 问题
如果就是不想改名字的话
{ test: /\.(jpg|png|gif|jpeg)$/, use: 'url-loader?limit=200,000&name=[name].[ext]'}
<!-- [name]保持原来的名字,[ext]保持原来的格式 -->
但是我也还想要 hash
{ test: /\.(jpg|png|gif|jpeg)$/, use: 'url-loader?limit=200,000&name=[hash:8]-[name].[ext]'}
Unexpected token / in JSON at position 113 while parsing near
json
文件不能写注释
'webpack-dev-server' 不是内部或者外部命令,也不是可运行的程序
--> 你没装
--> 配置文件明明说你装了 -> -> 我不是,我不是,我没有,就还是没装(没了配置,但是配置文件还有记录)
解决 webpack
默认无法处理 ES6
新特性 class static
webpack
只能默认处理一部分 ES6
的新语法,一些更加高级的 ES6
语法或者 ES7
语法, webpack
是处理不了的,这时候就需要借助第三方的 loader
来帮助 webpack
处理这些高级的语法,当第三方 loader
把高级语法转为低级语法以后,会把结果交给 webpack
去打包到 bundle.js
中
通过 babel
,可以帮我们将高级的语法转换为低级的语法
安装
我们可以在 webpack
中运行如下两套包,全装 babel
相关的 loader
功能
npm i babel-core babel-loader babel-plugin-transform-runtime -D
npm i babel-preset-env babel-preset-stage-0 -D
配置
打开 webpack
的配置文件,在 module
节点下的 rule
数组中,添加一个新的匹配规则:
{ test:/\.js$/, use: 'babel-loader', exclude: /node_modules/ }
// 配置 babel 的规则时,必须把 node_modules 选项排除掉
// 1.如果不排除的话,则 babel 会把 node_modules 中的所有第三方JS文件都打包翻译,会非常消耗 CPU ,且非常慢
// 2.哪怕硬钢都转换了,项目也无法正常运行
在根目录地下,新建 .babelrc
新建 .babelrc
的 Babel
配置文件,这是个 JSON
文件(必须符合 JSON
语法)
- 如下配置
{
"presets": ["env", "stage-0"],
"plugins": ["transform-runtime"]
}
如何解决 eslint-label
找不到问题
将 eslint
和 eslint-label
装一起:
npm i eslint eslint-label -D
webpack
和 Vue
在 webpack
中安装 Vue
: npm i vue -S
但是这种 Vue
不能支持我们直接像普通网页一样使用
import Vue from "Vue";
在包的查找过程中:
- 在项目根目录中有没有
node_modules
的文件夹 - 根据包名,找对应的文件夹
- 在
Vue
的文件夹中,找一个package.json
的包配置文件 - 在
package.json
文件夹中,查找一个main
属性 【 main 属性指定了这个包在被加载的时候的入口文件 】-
"main": "dist/vue.runtime.common.js"
// 这个文件暴露一个实例供我们使用,是Vue.js
的阉割版 - 以往那样我们用的是
"main": "dist/vue.js"
-
解决方案
- 直接将上述的配置修改成
"main": "dist/vue.js"
不大好 import Vue from '../node_modules/vue/dist/vue.js'
- 也可以在
webpack.config.js
中的添加
// 和 modules 平级
resolve: {
alias: { // 设置 vue 被导入包的时候的配置
'vue$': 'vue/dist/vue.js'
}
},
在 vue
的 runtime-only
中如何渲染一个组件?
- 只能够使用
render
函数 - 在
src
文件夹底下定义一个login.vue
文件- .vue 文件有三个部分
template
script
style
- .vue 文件有三个部分
- 在
main.js
中导入login
组件import login from './login.vue'
-
.vue
创造出来的文件,webpack
默认不识别,又要装第三方loader
:npm i vue-loader vue-template-compiler -D
- 这里面
vue-loader
的版本若为 15 则需要安装插件VueLoaderPlugin
,不然就不用了。
- 这里面
- 再去
webpack.config.js
去配置一下 - 然后在
render
调用写好的login
模板
.vue
文件中的 data
和 method
等属性
在 ES6
中,也通过规范的形式,规定了 ES6
中如何导入和导出模块:
ES6
中导入模块使用import '模块名称' from '表示路径'
-
ES6
中导出模块使用export default
和export
向外暴露成员-
export default
暴露出来的对象可以用任意对象名称接受import hah from '...'
- 在一个模块中,一个
export default
只允许暴露一次,而 'export' 可以暴露多次 -
export
:export var title = '小星星'
,在一个模块中,允许export default
和export
同时使用向外暴露成员, -
export
接受成员import { title } from '...'
,注意变量名必须要一致,但是也可以像import { title as title123} from '...'
为title
起别名。这种形式为【按需导出】,我们可以拿我们需要的变量
-
export default {
data() {
return {
msg: "123"
}; // 组件中的 data 必须是个 function
},
methods: {
show() {
console.log("调用了 login.vue 中的 show 方法");
}
}
};
webpack 和 vue-router
- 安装
npm i vue-router -s
-
import VueRouter from 'vue-router';
注意要先导入Vue
- 手动安装
VueRouter
:Vue.use(VueRouter);
- 创建路由对象....
但是我们如何显示组件呢?
如果像往常一样将 router-view
和 router-link
写到 el
所控制的元素中的话,会被 render
冲掉,所以我们写到 render
所加载的模板中去
webpack 和 vue 和 css
-
<style scoped>
可以在指定作用域 - 普通的 style 标签只支持普通的样式,如果想要启用 less 或者 scss 需要设置 lang 属性
<style lang="scss" scoped>
- 只要 style 标签是在组件中定义的,推荐都为 style 标签开启 scoped 属性
最好将路由模块抽离
初识 Mint-UI
MUI
不同于MInt-UI
,MUI
只是开发出来的一套好用的代码片段,里面提供了配套的样式、配套的HTML
;而Mint-UI
,是真正的组件库,是使用Vue
技术封装出来的成套的组件,可以无缝的和 Vue 项目惊醒集成开发
因此,MUI
和Bootstrap
感觉上类似,但是Mint-UI
只适用于Vue
项目
安装与配置,点击这里查看文档
安装:npm i mint-ui -s
导入所有的 mint-ui 组件
import MintUI from "mint-ui";
import "mint-ui/lib/style.css";
Vue.use(MintUI);
按需导入
借助 babel-plugin-component
,我们可以只引入需要的组件,以达到减小项目体积的目的。
首先,安装 babel-plugin-component
:
npm install babel-plugin-component -D
然后,将 .babelrc 修改为:
{
"presets": [
["es2015", { "modules": false }]
],
"plugins": [["component", [
{
"libraryName": "mint-ui",
"style": true
}
]]]
}
// 按需导入 mint-ui 组件
import { Button } from 'mint-ui';
// 使用 Vue.component 注册按钮组件
Vue.component(Button.name, Button);
使用
CSS component 导入后就可以使用
JS component 则是还是需要按需引用