前端的基础:HTML + CSS + JS (jQuery) + BootStrap~…
安装nodejs之前需要先安装一下python!
安装nodejs,无脑下一步即可!自动把你配置环境变量
什么是Nodejs?
以前我们编写 js 代码需要从浏览器执行,放在html中!
Nodejs ,就是可以在服务器端运行JS代码! 基于 Coogle 的 V8 引擎,可以脱离浏览器执行 js 代码!性
能较好!
如果确认自己安装好了呢? 安装完毕后,可以看到 node 和 npm 环境!
简单的 npm 使用 !
npm install vue
环境准备到此结束:
基本使用
1、创建文件夹 nodejs
2、创建我们的 test.js
3、打开终端
console.log(“hello,node”)
4、运行js程序
node 程序名.js
node 的服务器端开发(了解即可!)
02-server-app.js
const http = require('http')
http.createServer(function (request, response) {
response.writeHead(200, { 'Content-Type': 'text/plain' })
response.end('hello,node server')
}).listen(8080)
console.log("Server running at http://localhost:8080")
大部分现在的前端程序员,都会使用es6进行开发!浏览器一般都是只支持es5语法!
什么是 ES6 呢? 一个规范而已! JavaScript的下一代标准!
ECMAScript,在IDEA中默认配置ECMAScript5版本,我们要编写es6的语法,需要配置!
let 声明变量 和var声明变量的区别
// //1. var 声明的变量没有作用域, 作用域为包括它的函数作用域或者全局作用域。
//let 声明的变量是有作用域! 作用域是在定义它的块级代码以及其中包括的子块中,并且无法在全局作用域添加变量。
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}
{
var a = 0
let b = 1
}
console.log(a) // 0
console.log(b) // b is not defined
//结果信息:
console.log(aa,b);
^
ReferenceError: b is not defined
// 2.同一个块级作用域内, var 可以声明多次 let 可以声明一次
var m = 1
var m = 2
let n = 3
let n = 4 // Identifier 'n' has already been declared
console.log(m)
console.log(n)
// 3. var 会提升变量的作用域 let 不存在变量提升!
//在代码执行之前,会先扫描所有域内的var声明的变量,将其先进行初始化为undefined,然后再执行代码,也就是所谓的“提升”现象。
//但对于let声明的变量而言,则有所不同。在代码执行之前的扫描,同样也会对let变量进行“提升”,但并没有将其置为undefined。let定义的变量虽然经历了提升,但在没有执行到初始化它的代码前,该变量并没有被初始化,如果此时访问的话,会被置为ReferenceError错误。从代码块开始到执行到let变量初始化完毕这段时间,let变量已经被声明,但不可访问。这段时间被成为临时死区。下面是几个典型的展示临时死区问题的代码:
// let变量的作用域为function scope
function do_something() {
console.log(bar); // undefined
console.log(foo); // ReferenceError
var bar = 1;
let foo = 2;
}
// let变量的作用域为整段代码,
// prints out 'undefined'
console.log(typeof undeclaredVariable); // typeof对于未声明的变量返回undefined
// results in a 'ReferenceError'
console.log(typeof i);
let i = 10;
// let 变量为block scope,在初始化时使用,依然会视为临时死区,只有在初始化执行完后才可以使用
function test(){
var foo = 33;
if (true) {
let foo = (foo + 55); // ReferenceError
}
}
test();
// let 变量在for的block scope内进行了声明,n.a对应的是在本地作用域中的let变量n。在未初始化前,通过n.a进行了访问了n,因此报错
function go(n) {
// n here is defined!
console.log(n); // Object {a: [1,2,3]}
// let n1=n; 加上这一句就不会报错了
for (let n of n.a) { // ReferenceError
console.log(n);
}
}
go({a: [1, 2, 3]});
//
console.log(x) // undefined var声明的变量先使用后声明是没有报错的,但是let只有在声明的时候才会有作用域
var x = 'apple'
console.log(y) // Cannot access 'y' before initialization
let y = 'banana'
// 4.函数内也不能使用let关键字重新声明函数的参数;
function demo(ts) {
let ts = 'xk';
alert(ts);
}
demo(Hi); // 报错
报错原因是因为使用了let关键字重新声明了函数的参数ts;
总结:使用let关键字声明的变量只在跨级作用域中起作用,比较适合for循环中,同时也不会出现变量提升的现象;同一个代码块内,不可以重复声明相同的变量,也不可以重复声明函数内的参数。
常量
// 声明了常量之后就不允许在改变了!
// const PI = '3.141592653589793238462643'
// PI = 0 // Assignment to constant variable.
// 一但声明就必须初始化,否则救护报错
const MY_APP // Missing initializer in const declaration
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。
但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的;
结构赋值!
// 传统的
// let a = 1, b = 2, c = 3
// console.log(a, b, c)
// // es6
// let [x, y, z] = [1, 2, 3]
// console.log(x, y, z)
// 对象定义
let user = { name: 'zhangsan', age: 18 }
// 传统的
let name1 = user.name
let age1 = user.age
console.log(name1, age1)
// es6,取出对象中的所有值
let { name, age } = user // 结构的变量名必须和对象属性同名
console.log(name, age)
模板字符串!
let name = 'hello'
let age = 3
// 传统的,大家的习惯! ${}
let info = 'name:' + name + 'age:' + age; // 拼接字符串
// 字符串引号需要改为 ``
let infoes6 = `name: ${name} age:${age}` // 模板字符串,真正的前端开发
console.log(infoes6)
对象声明简写
const age = 3
const name = 'coding'
// 传统的
const person1 = { age: age, name: name }
console.log(person1)
// es6
const person2 = { name, age }
console.log(person2)
定义方法简写
const person1 = {
// 方法
sayHi: function () {
console.log("hi")
}
}
person1.sayHi();
// ES6
const person2 = {
sayHi() {
console.log('Hi 2')
}
}
person2.sayHi();
对象拓展运算符
let person = { name: 'coding', age: 3 }
let someoneOld = person // 引用赋值,地址不变
// 对象拷贝 是一个新的对象
let someone = { ...person }
someoneOld.name = 'kuangshen'
someone.name = 'kuangshen new'
console.log(person) //{ name: 'kuangshen', age: 3 }
console.log(someoneOld)//{ name: 'kuangshen', age: 3 }
console.log(someone)//{ name: 'kuangshen new', age: 3 }
默认的参数
function showInfo(name, age = 3) {
console.log(name + ',' + age)
}
// 测试
showInfo('coding', 18)
showInfo('coding')
showInfo('coding', undefined) //未定义的传进去之后就用默认的那个3就可以
showInfo('coding', null)//null的话传递过去之后,age的值也变成了null
箭头函数 参数 => 函数体
let arr = ["10", "5", "40", "25", "1000"]
let arr1 = arr.sort()
let arr2 = arr.sort((a, b) => a - b)
console.log(arr1)
// 需要使用排序的函数
// let arr2 = arr.sort((a, b) => {
// return a - b
// })
console.log(arr2)
// ()=>{}
var f1 = function (a, b) {
let result = a + b
return result
}
var f2 = (a, b) => {
let result = a + b
return result
}
var f3 = (a, b) => a * b //只有一行的话,大括号和return都可以省略掉
console.log(f3(2, 3));
未来,前端代码的底层大量可以看见这些代码,尤其是对接后端接口api
我们安装nodejs的时候,就有了 npm 的环境!
C:\Users\Administrator>npm -v
6.13.4
什么是 npm
NPM的全称是Node Package Manager,是一个NodeJS包管理和分发工具,已经成为了非官方的发布
Node模块(包)的标准。就好比maven,所有东西只要到导入依赖即可,npm 也是如此,npm
install,好比Linux 的 yum 安装!
测试
1、建立一个npm包 然后进入到这个目录中,然后npm init然后就看到npm目录下生成了 一个package.json文件,这个文件就相当于我们的pom.xml文件 依赖都会在这里面
2、测试初始化项目,理解npm如何管理前端依赖!
npm init
npm init -y # 直接生成默认的值!没有上面的哪些询问过程,直接以默认值生成package.json文件
修改 npm 镜像!
npm config list # 查看npm的配置信息
# 经过以下配置,就可以让所有的依赖下载通过 淘宝的镜像,这样会比较快!
npm config set registry https://registry.npm.taobao.org/
npm install xxx
下载依赖包!
1、npm install vue 安装指定依赖,默认是最新版本
2、npm install [email protected] 指定版本安装!
3、package.json 中管理了所有依赖版本控制,就如同 pom.xml
4、package-lock.json里面是依赖的具体信息,保证的是版本信息锁定
5、指定只在开发的时候使用 npm install --save-dev (等价-D) eslint
5、全局安装环境安装! -g npm install -g webpack
6、其他命令
npm update jquery # 更新包
npm uninstall jquery # 卸载包!
7.在上传到git上去或者其他项目的时候,node_modules文件夹是不存在的,因为这个文件太大了,所以一般都在ignore文件中将这个加上才可以
很多se6高级语法,浏览器是不支持的, Nodejs也不一定能运行!
转码器
Babel 是一个广泛的转码器!可以将 ES6代码转换为 ES5的代码! 语法会自动转换!
1、 安装 Babel
npm install -g babel-cli # 安装babel-cli
babel --version # 版本测试
6.26.0 (babel-core 6.26.3)
2、如何使用? 新建一个babel文件夹,然后使用npm init -y命令生成package.json
在 src 在编写js源代码,所以首先新建一个src的目录
编写.babelrc 配置文件 在根目录上创建.babelrc 文件,注意前面有点,后面没有后缀名的
{
"presets": [
"es2015"
],
"plugins": []
}
安装babel依赖 只有在开发的时候用,所以使用-D
npm install -D babel-preset-es2015
然后mkdir dist目录,这个是打包用的 也是在根目录下
输出测试 前面是想要输出哪个文件, 后面是输出到哪个地方去 这个的意思是将指定的js文件转码成浏览器可以识别的es5的规范
babel .\src\example.js --out-file .\dist1\dist.js
可以自定义脚本!
package.json 中设置
"scripts": {
"build": "babel .\\src\\example.js --out-file .\\dist\\dist.js"
},
npm run 脚本命令! npm run build
我们一般用的什么npm run auto npm run start 等等都是在这里配置的一段脚本
这里可以编写多个脚本!以后启动就不需要每一次都输入命令了!
npm run test
npm run dev
npm run start
本质就是一段脚本,以后看到类似的启动方式,就可以去找它的 scripts 脚本!
import!
发展
网站一步一步变成互联网化, js 代码越来越大,十分复杂!
js 又看到 java 、 import!
js 是否也可以模块化开发呢?
class 、 package 、moudle!
产生了两种模块化规范:
CommonJS 规范!
ES6模块化规范!
Commons JS
const sum = function (a, b) {
return a + b
}
const sub = function (a, b) {
return a - b
}
const mul = function (a, b) {
return a * b
}
const di = function (a, b) {
return a / b
}
// 导出这些方法供他人使用!
// module.exports = {
// sum: sum,
// sub: sub,
// mul: mul,
// di: di,
// }
// 如果名称相同,可以简写
module.exports = {
sum,
sub,
mul,
di
}
测试导入
const m = require('./四则运算.js')
console.log(m)
// 测试方法,正常输出
const r1 = m.sum(1, 2)
const r2 = m.sub(1, 2)
console.log(r1)
console.log(r2)
es6 模块化规范 我们现在开发使用的是这个规范,使用export修饰类,然后使用import来引入需要的类
export function getList() {
console.log('获取用户列表')
}
export function save() {
console.log('保存用户信息')
}
// import node不支持
import { getList, save } from './userApi.js'
getList()
save()
es6 第二种写法
userApi2.js页面:
export default userApi2{
getList() {
console.log("获取数据列表")
},
save() {
console.log("保存用户")
}
}
test.js页面
import user from './userApi2.js'
export default class test{
user.getList()
user.save()
}
记住一个点,node 不支持 es6 模块化语法,需要babel转义!
{
"name": "mokuaihua-es6",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "babel src -d dist" 就是将src目录直接全部转换为dist文件夹,会一一对应的
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-preset-es2015": "^6.24.1"
}
}
转码完成之后,再去执行就可以了
Webpack 是一个前端的资源、打包工具!
js less css png ====> .js
webpack 安装
1、安装
npm install -g webpack webpack-cli
webpack -v
2、初始化项目!
webpack 打包,可以让我们的代码不是那么繁琐,可以实现复用!
1.还是那个规则,首先新建一个webpack的目录
2.然后npm init -y 默认的值生成package.json文件
3.编写我们自己的测试代码:
common.js
exports.info = function (str) {
document.write(str)
}
util.js
exports.add = function (a, b) {
return a + b;
}
style.css:
body{
background: hotpink;
}
main.js
require("./style.css")
const common = require('./common.js')
const utils = require('./utils.js')
common.info('hello,World!' + utils.add(100, 200))
4.编写我们的webpack的配置文件:
const path = require('path') // Node.js 的内置模块,取当前的路径
module.exports = {
entry: './src/main.js', 配置文件的入口,就是程序的入口
output: {
path: path.resolve(__dirname, './dist'), // 输出路径
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/, // 打包规则映射到 css 结尾的文件上!
use: ['style-loader', 'css-loader']
}
]
}
}
5.然后执行一下 webpack --mode=development,提示出错了:
y一般这种错误是没有安装依赖包,所以我们把这个依赖包安装一下:
npm i style-loader --save-dev
npm i css-loader --save-dev
然后在执行前面的语句webpack --mode=development
6.然后就能看到dist目录下生成了 一个bundle.js文件
7.我们可以将这个命令写在脚本里面,放入package.json中,这样就可以使用npm run xxx来执行了:
8.然后看我们的那个bundle.js文件:
都是看不太懂,是打包后的,防止别人看到我们的源码,但是如何使用呢>新建一个inde.html页面,即可
<body>
<script src="./dist/bundle.js">script>
body>
9.然后选中这个index.html 右键运行:
来自互联网:全部的规则
module.exports = {
// 提供 mode 配置选项,告知 webpack 使用相应模式的内置优化
mode: 'production',
// 基础目录,绝对路径,用于配置中解析入口起点(entry point)和 loader 默认使用当前目录,
但是推荐在配置中传递一个值
context: 'C:\\project\\vueTest',
// 此选项控制是否生成,以及如何生成 source map 使用 SourceMapDevToolPlugin 进行更细
粒度的配置。查看 source-map-loader 来处理已有的 source map
devtool: false,
// 此选项可以配置是否polyfill或mock某些Node.js全局变量和模块。这可以使最初为Node.js环
境编写的代码。在其他环境中允许
node: {
setImmediate: false,
process: 'mock',
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
},
// 默认为 ./src
// 这里应用程序开始执行
// webpack 开始打包
output: {
// path webpack 如何输出结果的相关选项
path: 'C:\\project\\vueTest\\dist', // string
// 所有输出文件的目标路径
// 必须是绝对路径(使用node.js的path模块)
filename: 'js/[name].[contenthash:8].js',
// 入口分块(entry chunk) 的文件名称模板
publicPath: '/',
// 此选项决定了非入口(non-entry) chunk 文件的名称。有关可取的值的详细信息,请查看
output.filename 选项。
chunkFilename: 'js/[name].[contenthash:8].js'
},
//解析 配置模块如何解析,例如,挡在ES2015中调用import "loadsh",resolve选项能够对
webpack查找“loadsh”的方式取做修改
resolve: {
// 创建import或require的别名,来确保模块引入变得简单、例如,一些位于 src/ 文件夹下
的常用模块:
alias: {
'@': 'C:\\project\\vueTest\\src',
vue$: 'vue/dist/vue.runtime.esm.js'
},
// 自动解析确定的扩展。默认值为['.wasm', '.mjs', '.js', '.json']
// 能够使用户在引入模块时不带扩展: 如import File from '../path/to/file';
extensions: [
'.js',
'.jsx',
'.vue',
'.json'
],
// 告诉webpack 解析模块时应该搜索的目录,
// 绝对路径和相对路径都能使用,但是要知道它们之间有一点差异
// 通过查看当前目录以及祖先路径,相对路径将类似于Node查找‘node_modules’
modules: [
// 模块别名列表
'node_modules',
'C:\\project\\vueTest\\node_modules',
'C:\\project\\vueTest\\node_modules\\@vue\\cli-
service\\node_modules'
]
},
// 这组选项与上面的resolve对象的属性集合相同,但是仅用于来解析webpack的loader包。
resolveLoader: {
modules: [
'C:\\project\\vueTest\\node_modules\\@vue\\cli-plugin-
eslint\\node_modules',
'C:\\project\\vueTest\\node_modules\\@vue\\cli-plugin-
babel\\node_modules',
'node_modules',
'C:\\project\\vueTest\\node_modules',
'C:\\project\\vueTest\\node_modules\\@vue\\cli-
service\\node_modules'
]
},
// 模块 module 决定了 如何处理项目中的不同类型的模块
module: {
// 防止webpakc解析哪些任何与给定正则表达式匹配的文件。忽略的文件中不应该含有
important,require,define的调用,或任何其他导入机制忽略大型的libaray可以提高构建性能
noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/,
// 模块规格 (匹配loader,解析器等选项)
// loaders webpack可以使用loader来预处理文件。这允许你打包除javascript之外的任何
静态资源,你可以使用node.js来更简单的编写自己的loader
rules: [
/* config.module.rule('vue') */
{
test: /\.vue$/,
use: [
{
// 有一些性能开销较大的loader之前添加此loader,可以将结果缓存到磁
盘里
loader: 'cache-loader',
options: {
cacheDirectory:
'C:\\project\\vueTest\\node_modules\\.cache\\vue-loader',
cacheIdentifier: 'c12e2af6'
}
},
{
// 以及 `.vue` 文件中的 `