1. 前端工程化 (前端模块化)
- 传统开发模式的问题:
命名冲突: 多个js文件之间,如果存在重名变量,会发生变量覆盖;
文件依赖: js文件之间,无法实现相互引用; - 通过模块化,解决上述问题:
模块化就是,把单独的一个功能,封装到一个模块 (文件) 中,模块之间相互隔离,但可以通过特定的接口,公开内部成员,也可以导入其它模块;方便代码的重用,以及后期维护;
浏览器端模块化规范 (已落后)
AMD(Asynchronous Module Definition,异步模块定义):代表产品为:Require.js
CMD(Common Module Definition,通用模块定义):代表产品为:Sea.js
服务器端模块化规范
node 中的 CommonJS规范:
1.CommonJS中的模块,分为 单文件模块 与 包;
2.每一个文件,都是一个模块,都拥有独立的作用域;
3.导入模块成员: require('模块标识符')
4.导出模块成员: module.exports 和 exports
ES6 模块化规范 (推荐使用)
//浏览器端和服务器端,通用的模块化规范
1.每一个js文件,都是一个独立的模块;
2.导入模块成员,使用import关键字;
3.暴露模块成员,使用export关键字;
2. Node.JS 中通过 babel 体验 ES6模块化
/*node中默认支持,CommonJS服务器端,模块化规范;对ES6的模块化,支持的并不好;
需要结合 babel第三方插件,在node中,体验高级的 ES6特性;
*babel:语法转换工具,把高级的有兼容性的 js代码,转换为低级的,没有兼容性的javascript代码*/
1.终端:npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
安装babel相关的依赖包
2.npm install --save @babel/polyfill 安装第三方插件
3.根目录中创建 babel.config.js文件,写入如下代码:
const presets = [ //语法转换数组,提供了可能用到的,语法转换插件;
["@babel/env",{
targets:{ //转换完成后,要支持下面的浏览器;
edge:"17",
firefox:"60",
chrome:"67",
safari:"11.1"
}
}]
]
module.exports = { presets } //暴露出去,供babel使用;
4.根目录中,创建index.js 入口文件: console.log("ok");
终端:npx babel-node ./index.js //运行babel,执行index.js文件
输出'ok',证明babel 已配置完成了,支持使用高级 ES6特性了,比如模块化导入;
2.1 默认导入与导出
# m1.js
let a = 10
let d = 30 //没有暴露出去,外面访问不到
function show() {
console.log('111')
}
//将本模块中的,私有成员暴露出去,供其它模块使用
export default {
a,
show
}
/*一个模块只能有一个,默认导出 export default;可以有多个按需导出;
*默认导出和按需导出,可同时存在,不冲突;*/
----------------------------------------------------------------------------------------
# index.js -->如果一个模块中,没有向外暴露任何成员,其它模块导入这个模块时,默认接收一个空对象{}
import m1 from './m1.js'
console.log(m1)
//右键->在终端中打开: npx babel-node index.js --> {a:10,show:[Function:show]}
//导入模块成员:import 模块名 from 模块标识符
2.2 按需导入与导出
# m1.js
export default {
//默认导出和按需导出,可以同时存在,不冲突;
}
export let s1 = 'aaa';
export let s2 = 'ccc'
export function say(){
console.log("222")
}
# index.js
//import m1 只包括,默认导入;没有按需导入'{}',即使有按需导出,也访问不到;
import m1,{ s1, s2 as ss2, say } from "./m1.js"
console.log(s1,ss2,say) //ss2别名,s2不能再用了;
//npx babel-node index.js --> aaa ccc [Function:say]
2.3 直接导入并执行模块中的代码
//只是单纯的,执行模块中的代码,并不需要得到,模块中向外暴露的成员;
# m2.js
for (let i = 0; i < 3; i++) {
console.log(i)
}
# index.js
import './m2.js' //直接导入并执行代码
//npx babel-node index.js --> 0 1 2
3. webpack的概念
webpack 前端项目 打包工具;提供了模块化支持,代码压缩混淆,解决 js兼容问题,性能优化等,提高了开发效率,和项目的可维护性;
3.1 创建列表隔行变色项目
1.新建空白文件夹 -->npm init -y (初始化包管理,配置文件 package.json)
//传输文件没有 node_modules 文件夹,运行 npm i 重新下载
2.新建 src源代码目录 -->index.html
<script src='./index.js'></script>
初始化首页结构:ul>li {这是第$个li} *9
3.npm install jquery –s 安装jQuery
4.通过模块化的形式,导入并使用jQuery,实现隔行变色;
# index.js
import $ from "jquery" //导入jquery,ES6模块化语法;
$(function(){
$("li:odd").css("background","cyan");
$("li:odd").css("background","pink");
})
/*F12检查,显示第一行报错;因为import $ from "jquery" 属于ES6语法,浏览器中可能会存在
JavaScript 的兼容性问题;用 webpack 把有兼容性的代码,转换成没有兼容性的代码,再重新导入
3.2 安装和配置 webpack
1)npm install webpack webpack-cli -D 安装 webpack相关包;
2)根目录中,创建 webpack.config.js 配置文件:
module.exports = {
mode:"development"
}
// mode用来指定项目编译模式:development(开发模式),不压缩混淆代码,打包速度快;
// production(发布模式),对转换出来的代码,压缩混淆,体积小;一般项目上线时用;
3)package.json 配置文件中,scripts节点下,新增 dev脚本(脚本指令webpack):
"scripts":{
"dev":"webpack"
}
// scripts节点下的脚本,通过 npm run 执行;
4)终端中运行:npm run dev;执行 dev脚本,对应的 webpack命令,进行项目打包;
自动创建 dist文件夹 --> main.js文件;把 main.js 导入到 index.html 中;
3.3 设置打包的入口/出口
// webpack 4.x 版本中默认约定:
打包入口文件为 src -> index.js
打包输出文件为 dist -> main.js
// 修改打包的入口与出口,可以在 webpack.config.js 中新增如下配置信息:
const path = require("path"); // 导入 node.js 中,操作路径的模块
module.exports = {
mode:"development",
entry: path.join(__dirname,"./src/xx.js"), // 打包入口文件的路径
output:{
path:path.join(__dirname,"./dist"), // 输出文件的存放路径
filename:"res.js" // 输出文件的名称
}
}
3.4 配置 webpack 自动打包功能
1) npm install webpack-dev-server -D 安装自动打包工具;
2) 修改 package.json -> scripts 节点下的 dev命令:
"scripts":{
"dev":"webpack-dev-server"
} //webpack-dev-server 会启动一个实时打包的 http服务器,监听项目中代码的变化,自动打包
3) 将index.html 中 script引用路径 'dist/buldle.js' 修改为根路径下的 '/buldle.js';
<script src="/bundle.js"></script>
4) 运行: npm run dev,重新打包;
5) 访问 http://localhost:8080/src(/index.html),查看打包效果;
/*webpack 打包生成的输出文件 buldle.js,并没有放到物理磁盘上,而是放到了内存中,它是虚拟的、
看不见的;默认放到了项目根目录中,所以在引入时,直接'/'根路径;dist/buldle.js 文件,看的到
3.5 html-webpack-plugin 生成预览页面
//访问 http://localhost:8080/ 时,实现页面预览功能:
//复制index.html ,放到网站根目录下,浏览器访问路径中,默认自动打开 index.html文件
1) npm install html-webpack-plugin -D 安装生成预览页面的插件
2) webpack.config.js 头部区域,添加配置信息:
// 导入生成预览页面的插件,得到一个构造函数
const HtmlWebpackPlugin = require('html-webpack-plugin')
const htmlPlugin = new HtmlWebpackPlugin({ // 创建插件的实例对象
template: './src/index.html', // 要复制的模板文件
filename: 'index.html' //生成新页面的名称,存放在内存中,目录中不显示
})
//向外暴露的配置对象,新增如下节点:
module.exports = {
.........
plugins: [ htmlPlugin ] //plugins数组是 webpack打包期间,用到的一些插件
}
---------------------------------------------------------------------------
// 打包完后,自动弹出页面
package.json --> scripts节点
"scripts": { //在127.0.0.1:8888 端口,打开页面
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 8888"
}
//--open 打包完后,自动弹出页面;--host 配置 IP地址;--port 配置端口
4. webpack 中的加载器
- webpack 只能打包 js模块,非 js 模块,需要调用 loader加载器,才能打包;
- loader 加载器,协助 webpack 打包特定的,文件模块,比如:
.less-loader:打包处理 .less 相关的文件
.sass-loader: 打包处理 .scss 相关的文件
.url-loader: 打包处理css中与url路径有关的文件
.babel-loader: 处理高级 js语法 的加载器
.postcss-loader
.css-loader,style-loader
webpack 中 加载器的使用
//use 数组中,指定的loader,顺序是固定的;多个loader,从后往前调用;
1)打包处理css文件:
1.npm install style-loader css-loader -D
2.webpack.config.js 的 module --> rules数组,配置如下规则:
module.exports = {
......
plugins:[ htmlPlugin ],
module : {
rules:[ //rules[]数组,存放所有的 loader规则
//test:匹配的文件类型,支持正则;use:该文件类型,需要调用的loader
{test:/\.css$/,use:['style-loader','css-loader']}
]
}
}
3.index.js中,引入import './css/1.css',
4.npm run dev //进行webpack打包; 为什么不在index.html中引入css文件???
2)打包处理less文件:
1.npm install less-loader less -D
2.rules:[
{test:/\.less$/,use:['style-loader','css-loader','less-loader']}
] //之前如果没安装'style-loader','css-loader',需要安装;
3)打包处理sass文件:
1.npm install sass-loader node-sass -D
2.rules:[
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader']}
] //sass的后缀名是.scss;安装sass-loader失败时,大部分是网络原因;
4)通过 postcss 自动添加css的兼容性前缀(-ie-,-webkit-)
<input placeholder='ceshi'> -->index.html
::placeholder{ //伪元素选择器
color:red;
} --> 1.css
//伪元素选择器,有浏览器兼容问题,ie浏览器不支持;
1.npm install postcss-loader autoprefixer -D //安装插件
2.根目录中创建 postcss.config.js:
const autoprefixer = require("autoprefixer"); //导入自动添加前缀的插件
module.exports = {
plugins:[ autoprefixer ] //挂载插件
}
3.webpack.config.js -->module --> rules数组
rules:[ //修改 css的 loader,新增一个'postcss-loader'
{ test:/\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader']}
]
5)打包样式表中的,图片和文件:(webpack默认处理不了,样式表中的路径)
//box{background:url('../img/1.png')}
1.npm install url-loader file-loader -D
2.rules:[ //bmp之后是字体文件的后缀名
{ test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
use: 'url-loader?limit=16940'
}
]
//?之后是参数项:limit 用来指定图片的大小,单位是字节(byte);
//只有小于 limit的图片,才会被转为 base64图片;大于或等于limit,图片地址是url路径
6)打包处理 js文件中的 高级语法:安装 babel系列的包,将之打包为,兼容的 js代码
1.安装babel转换器: npm install babel-loader @babel/core @babel/runtime -D
2.安装babel语法插件包: npm install @babel/preset-env @babel/plugin-transform-runtime
@babel/plugin-proposal-class-properties -D
3.根目录,创建 babel.config.js文件
module.exports = {
presets:["@babel/preset-env"],
plugins:[ "@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties" ]
}
4.rules:[
{test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }
] //exclude 为排除项,表示 babel-loader 不需要处理 node_modules 中的 js文件;
/*<script>
script标签中,可以直接使用js高级语法;improt引入js文件时,不能使用???
</script>*/
5. Vue 单文件组件
//传统组件的问题:
1.全局定义的组件,必须保证组件名,不重复;
2.字符串模板,缺乏语法高亮;
3.不支持 CSS:当 html和Js 组件化时,css被遗漏了;
4.没有构建步骤限制:只能使用 html 和 ES5JavaScript,不能使用预处理器 (如babel)
//解决方案: 使用 Vue单文件组件,后缀名.vue
<template>
<!-- 组件的 模板内容区域 -->
</template>
<script>
//组件的业务逻辑区,暴露配置对象
export default {
data: () {
return {} //定义私有数据
},
methods: {} //处理函数
// ... 生命周期函数等,其它业务逻辑
}
</script>
<style scoped> //scoped 私有的;防止组件之间,样式冲突;
//组件的样式 .css
</style>
webpack 中配置 vue组件 的加载器
// webpack 默认只能处理 js文件,不能处理 .vue文件;
1.npm i vue-loader vue-template-compiler -D
2.webpack.config.js 文件中,添加 vue-loader 配置项:
const VueLoaderPlugin = require('vue-loader/lib/plugin')
plugins: [
new VueLoaderPlugin() //引入这个插件
...... 其它插件
],
module.exports = {
module: {
rules: [
{ test: /\.vue$/, loader: 'vue-loader' }
]
}
}
webpack 项目中使用 vue
1.npm i vue –S 安装vue
2.在 index.js 入口文件中,导入 vue构造函数: import Vue from 'vue'
3.导入 App 根组件 import App from './components/App.vue'
创建 vue实例对象,并指定要控制的 el区域
通过 render函数,渲染 App根组件 (把指定的组件,渲染到 el区域)
#index.js
// 1.导入 Vue 构造函数
import Vue from 'vue'
// 2.导入 App 根组件
import App from './components/App.vue'
const vm = new Vue({
el: '#app', // 3.指定要控制的区域;
render: h => h(App)//4.要渲染那个组件,就把那个组件放在这里
})
//在webpack项目中,使用render函数,来渲染指定的组件,componet,template就不要用了;
//因为webpack中导入的vue,是阉割版的vue,只支持render函数渲染组件,不支持template属性等
#index.html
<div id='app'>
App根组件 在这里显示
</div>
webpack 项目 的打包与发布
//上线之前,需要通过 webpack,进行整体打包;
//可通过 package.json 配置打包命令;该命令会加载,根目录中的 webpack.config.js文件
"scripts": {
"build": "webpack -p",// 用于打包的命令
//用于开发调试的命令
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 3000"
}
终端:npm run build;//会执行'webpack -p',读取webpack.config.js文件中的,相关打包配置
--> 生成新的 dist文件夹 (index.html bundle.js)
6. Vue脚手架
Vue脚手架: 是一个命令行工具,用于快速生成 Vue项目 基础架构
npm install -g @vue/cli (安装3.x版本 脚手架);查看版本号:vue -V
1.基于 命令行的方式,创建 Vue项目
cmd (window图标 + r):vue create my-project //项目名称,不能有中文
→ Manually select features(手动创建项目)
→ 选中安装的功能,空格'*'选中
→ 是否选用,历史模式的路由: n (安装hash模式的路由)
→ ESLint语法版本选择:ESLint + Standard config (标准类型的eslint)
→ 何时进行ESLint语法校验:Lint on save
→ babel,postcss等配置文件如何放置:In dedicated config files(单独使用文件进行配置)
→ 是否保存为模板:n
使用哪个工具安装包:npm
cd 创建的项目名称 //到新建的根目录里
npm run server //运行
复制地址,到浏览器打开;
2.基于 UI图形化界面,创建 Vue项目
命令:vue ui
在自动打开的,创建项目网页中,配置项目信息;
3).基于2.x的旧模板,创建 Vue项目
安装包: npm install -g @vue/cli-init
vue init webpack my-project //项目名称
Vue 脚手架 生成的项目结构:
node_modules:依赖包目录
public:静态资源目录
src:组件源码目录
assets:可能用到的资源
components:组件目录
views:视图组件目录
App.vue:根组件;承载项目中所有组件的根组件;
main.js:打包入口文件
router.js:路由相关配置
babel.config.js:babel配置文件
package.json 包管理配置文件
package-lock.json
.eslintrc.js eslint配置文件
Vue 脚手架的 自定义配置
/*通过 package.json 配置项目
*不推荐;package.json 主要用来管理,包的配置信息,为了方便维护,
推荐将 vue脚手架 相关的配置,单独定义到 vue.config.js文件中*/
"vue":{
"devServer":{
"port":"9990", //端口号
"open":true //打包完成后,自动打开浏览器
}
}
//根目录中,创建 vue.config.js 文件,覆盖默认配置
module.exports = {
devServer:{
port:8888,
open:true
}
}
npm run serve 运行项目
7. Element-UI
Element-UI:基于vue 2.0的,桌面端组件库;
1) 基于命令行方式,手动安装 element-ui
npm i element-ui –S 安装依赖包
main.js 导入 Element-UI 相关资源:
// 导入组件库 (组件的ui结构)
import ElementUI from 'element-ui';
// 导入组件相关样式 (css)
import 'element-ui/lib/theme-chalk/index.css';
// 配置 Vue 插件 通过vue.use( ),把 elementUI 安装到 Vue上
Vue.use(ElementUI);
//引入组件按钮,npm run server 运行服务器 测试
2) 基于图形化界面 自动安装
vue ui --> 打开图形化界面 --> 插件 --> 添加插件,搜索 vue-cli-plugin-element 安装
安装完成后,弹出"配置插件"面板 --> 选中按需导入
打开项目的 main.js
import './plugins/element.js' -->找到element.js路径,打开