Appearance
Node.js
学习目标
- 【了解】node.js的概念
- 【掌握】初始化项目
- 【掌握】NPM的常见命令
- 【掌握】yarn的常见命令
- 【了解】webpack的作用
node.js的基本概念
传统浏览器中的JS
在整个U2课程阶段,我们都在学习javascript这门编程语言,现在问大家这么一个问题:
JS由哪几部分组成?
相信大家都能很快的回答说出是由 ECMAScript DOM和BOM组成,你的回答在之前的课程阶段完全正确!
浏览器的JS = ECMAScript+DOM+BOM
但现在,这个回答需要做出一点改进,随着javascript这门语言的快速发展,它已经不是浏览器上的一个简单脚本语言,它不仅仅能在浏览器上创造神奇的交互效果,它还将触角伸到了服务器上,如今的JS已经可以运行在服务器上,实现传统后端语言的功能了!
服务器中的JS
如何将JS运行到服务器上?那就要借助我们今天的主角—Node.js了!
首先我们得明确,Node.js不是一门全新的服务端语言,它是和浏览器一样,是javascript的一个运行环境,在这个运行环境中,JS被赋予了更强大的功能,这些功能实现了JS对服务器的操作!
一起来看看官方对于node.js的定义:Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。
相较于浏览器端的JS,node.js去掉了DOM和BOM(服务器端哪来的页面),仍然保留了ECMAScript的核心语法,这让前端开发人员不必改变它们书写代码的习惯,加入了大量的核心模块,通过这些核心模块,我们可以进行文件操作,服务器创建,进程管理等一系列操作。
node中的JS = ECMAScript + 模块系统
听到这里,大家是不是有点迫不及待地想要开始模块系统的学习了?但在今天,我们不会深入探讨Node.js,这部分内容的知识体系非常庞大,我们会另外设置课程内容来说明它,今天我们仅仅需要了解一下Node.js是什么即可,当然还有一个重要的工具—NPM包管理工具!
初始化项目
node环境的安装
在学习包管理工具之前,请确保你的电脑上已经安装了Node.js的环境,可以自行到官网下载当前的稳定版本(当前版本为v18+版本),打开命令行工具,通过node -v
命令确保环境的正确安装。
只要显示出了版本号,说明node环境安装成功!
传统的项目结构和npm初始化项目
我们先来回忆一下之前项目代码的目录结构,例如我们的项目存放在一个叫做project的文件夹中:
index.html ----这个文件是用来书写主页内容的结构
list.html ----列表页结构
login----登录页结构
css----书写样式的文件夹
----index.css首页样式
----list.css列表页样式
----login.css登录页样式
js----书写交互的文件夹
----index.js 首页的JS文件
----list.js列表页的JS文件
----login.js登录页的JS文件
libs----存放第三方依赖的文件夹
----jquery.js 引入的jq文件
----swiper.js引入的轮播图插件
在传统的项目结构中,我们通过在html文件中引入各种css,js文件来组织结构,大家现在关注一下libs这个文件夹,这里面存放着大量第三方的插件和依赖,传统工作模式中,我们会在html文件中通过<script>
和<link>
标签来引入它们,维护小的项目,这样做似乎没有什么问题,但当你的项目足够复杂,这里的第三方插件可能达到几十上百个,当我需要查看我到底安装了哪些依赖,以及这些依赖是什么版本的时候,我必须进到这个文件中一一查看,这样做的效率必然非常低下,还有一个更可怕的问题,当你把这个项目分享给别人的时候,你必须要把这些第三方依赖一起传给他人,而往往第三方依赖的体积都比较庞大,效率更低下了。这个时候我们迫切需要能优化第三方依赖管理的解决方案了,Node.js为我们提供了它!
我们现在仍然创建一个名为project的文件夹来保存我们的项目,你自己书写的代码仍然可以像之前那么管理,我们的关注点放到第三方依赖上
右键点击项目文件夹,选择在集成终端中打开,然后输入命令npm init -y
,此时你会在在项目目录下看到一个自动生成的文件package.json
,你可以把它看作一个依赖管理的说明书,现在我们就要学习一下如何来下载第三方依赖。
从今天开始,我们将很少使用传统的下载依赖的方式,基于node环境,我们通过命令行的命令,可以实现对第三方包的管理,在正式下载第一个依赖之前,我们需要明确一件事情,就是官方的NPM服务器是部署在国外的,直接从国外服务器下载文件速度是很慢的,如何解决这个问题呢?我们可以通过设置淘宝镜像的方式来实现
输入命令
npm config set registry https://registry.npm.taobao.org
设置淘宝镜像
输入命令
npm config get registry
确保设置成功
现在我们通过命令来下载一个函数库lodash
输入命令
npm install lodash--save
这时你会发现在项目目录下自动生成了一个node_modules的文件夹,lodash就放在其中,这个名为node_modules是系统自动生成的,不要修改它的名称,以后通过NPM下载的所有第三包都会自动放在其中,而此时打开package.json说明书,你会在dependencies这个字段中看到刚刚安装的lodash和它的版本号。
现在我们对刚才的命令做一些解释:
install 表示安装的意思 可以简写为i
install 后面跟上你需要安装的包的具体名称 你可以在npm.js官网上找到准确名称
--save 表示你将这个包安装到了生产环境下,可以简写为-S
常见NPM命令
我们把NPM常见的命令都做一个汇总:
1.安装指定第三方包 如果希望全局安装 可以加上-g
npm i 包名 -g
2.卸载指定第三方包
npm uninstall 包名
3.更新指定第三方包
npm update 包名
4.安装package.json中的所有依赖
npm i
目前掌握这4个即可实现基本的安装卸载和更新,当然还有更多命令在更高级的场景中使用。
常见的Yarn命令
除开npm命令,现在还提供了yarn命令来实现包管理,首先需要全局安装yarn
npm i yarn -g
我们用yarn命令来实现刚才的操作
yarn global add 包名
yarn remove 包名
yarn upgrade 包名
yarn install
在之后的工作开发中,你可以任选npm或者yarn的一种方式来完成第三方的包管理了!
webpack的使用和概念
前端工程化的由来
大家有没有思考过一个问题,我们在编辑器中书写的代码和最终上线的代码是完全一致的吗?
以我们的刚才的node.js官网为例,可以通过右键查看源代码的形式来查看它的线上代码,你会发现它所有的代码都被压缩到了一起,完全无法阅读,而我们在书写代码的时候显然不是这种格式,这说明从开发环境到生产环境,代码似乎被谁加工了一下,这里要需要引出webpack了。
在当前的前端业务环境中,为了更好适应浏览器适配工作,我们经常需要对开发环境中的代码进行压缩(减小体积),转义(解析less这种预编译语言),编译(将ES6的最新语法转为ES3版本的老语法)等一些操作(我们称之为前端工程化),那么我们需要一个强大的工具来完成这些事情,而webpack就是最流行的前端工程化工具。
webpack初体验
一起看看官网的定义:webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)
webpack是基于node.js开发的前端工具,它的核心是通过依赖关系将所有的资源模块进行打包,一起来到编辑器中来操作一下。
首先我们得在项目中安装webpack,我们新建一个名为webpack的文件夹,初始化项目后在集成终端中输入以下命令:
npm i webpack webpack-cli
我们需要安装2个包,其中第二个包是webpack的命令行工具。我们当前学习的是最新的webpack5版本。
好的,正式开始,模拟一下正式的工作环境,我们在webpack项目下新建一个src目录用来书写业务代码,新建一个index.html文件来放置项目结构,我们现在的目录结构应该是这样的:
现在我们在src目录下新建一个js目录,下面新建一个utils.js文件来书写我们的工具模块,在这个文件中我们通过箭头函数的形式书写一个简单的求和函数,然后通过ES6的模块化语法将他导出。然后再新建一个api.js文件来书写我们的接口请求模块,在这个文件中我们通过Common.js的规范导出。
然后我们在src目录下新建一个index.js作为我们的所有js的主入口,在这个文件中引入刚才书写的求和函数和接口函数。
最后我们在index.html中引入刚才js的主入口文件,尝试运行一下它。浏览器报错了!那如何解决这个问题呢,此时我们的webpack出马了,我们在命令中输入命令webpack
,稍等一会我们的项目目录下新增了一个名为dist的目录,下面有一个main.js的文件,你可以把它理解为webpack将原来的index.js加工后的输出,然后我们尝试引入这个main.js文件然后重新执行它。
经过刚才的体验,我们体会到了webpack的能力,经过它加工后的js文件解决了模块导入的兼容问题,我们正式开始介绍一下它的核心概念。
webpack核心概念
在正式介绍核心概念之前需要明确一点,我们操作webpack是通过书写配置文件的形式控制其工作行为,我们需要在项目目录下新建一个名为webpack.config.js的文件,它是我们书写配置的具体地方,注意这里需要使用CommonJS的模块规范。
入口(entry) 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
可以通过在 webpack 配置中配置
entry
属性,来指定一个入口起点(或多个入口起点)。默认值为./src/index.js
。接下来我们看一个
entry
配置的最简单例子:我手动地将入口文件设置为了src目录下的test.js文件,再执行webpack打包命令后,我们在dist目录下可以看到打包后的文件来自于test.js,我们可以感受到我们修改了打包入口的位置。
webpack.config.js
jsmodule.exports = { entry: './src/test.js' };
出口(output)属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为
./dist
。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个output
字段,来配置这些处理过程:webpack.config.js
jsconst path = require('path');//引入node.js内置的path模块 用来处理路径 module.exports = { entry: './src/test.js', output: { path: path.resolve(__dirname, 'output'), filename: 'my-webpack.js' } };
再次通过webpack执行打包,打包后的文件将输出到output目录下的my-webpack.js文件。
模块(loader)loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript和JSON)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
我们以css文件为例,来看看webpack是如何来处理样式文件的。
首先,我们在项目src目录下新建一个.css文件,随意输入点样式。然后我们在test.js(也就是刚刚设置的入口)中引入这个样式文件。
如果这个时候直接打包,我们会看到一句这样的报错信息
You may need an appropriate loader to handle this file type
webpack告诉我们不能直接处理非js文件,需要一个合适的loader来处理它。
那么我们需要安装这个loader,通过
npm i css-loader
命令安装对应的插件。然后修改配置文件webpack.config.js
jsconst path = require('path');//引入node.js内置的path模块 用来处理路径 module.exports = { entry: './src/test.js', output: { path: path.resolve(__dirname, 'output'), filename: 'my-webpack.js' }, module:{ rules:[ { test:/\.css$/, use:['css-loader'] } ] } };
执行打包,错误消失,但现在的问题是样式似乎没有作用到我们的页面,我们在index.html中发现确实没有引入样式,我们还需要安装一个
style-loader
,然后use:['style-loader','css-loader']
,再次打包,样式成功起作用。loader是webpack最核心的概念,通过loader,webpack能处理各种类型的文件,我们当前的课程只做一些基本了解,如果要深入掌握个各种loader的配置,可以参考官方文档。
插件(plugins)插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!
插件目的在于解决 loader 无法实现的其他事。
还是我们上面的例子,我们刚才通过
style-loader
让样式生效其实中通过将样式放置到头部的style标签实现的,如果我希望引入外部css文件的形式呢?那我们应该怎么办,这时就需要使用插件了。而且此时就不必再使用style-loader
了。首先安装对应的插件
mini-css-extract-webpack-plugin
,然后对应修改配置文件webpack.config.js
jsconst path = require('path');//引入node.js内置的path模块 用来处理路径 const miniCssExtractPlugin = require('mini-css-extract-plugin');//引入对应插件 module.exports = { entry: './src/test.js', output: { path: path.resolve(__dirname, 'output'), filename: 'my-webpack.js' }, module:{ rules:[ { test:/\.css$/, use: [miniCssExtractPlugin.loader, 'css-loader'] } ] }, plugins: [ new miniCssExtractPlugin({ filename: `[name]_[contenthash:8].css`, }) ] };
执行打包操作,会发现css文件被单独打包到输出目录,然后在html模板中引入它即可!
插件的功能非常强大,在将来成为高级前端工程师的路上,你会慢慢接触到自己配置更多的插件!
模式(mode)这个概念很好理解,刚刚我们在执行打包的时候一直有一个警告,webpack在打包时候需要区分是生产还是开发环境,通过选择
development
或production
之中的一个,来设置mode
参数。webpack.config.js
jsconst path = require('path');//引入node.js内置的path模块 用来处理路径 const miniCssExtractPlugin = require('mini-css-extract-plugin');//引入对应插件 module.exports = { mode:'development' entry: './src/test.js', output: { path: path.resolve(__dirname, 'output'), filename: 'my-webpack.js' }, module:{ rules:[ { test:/\.css$/, use: [miniCssExtractPlugin.loader, 'css-loader'] } ] }, plugins: [ new miniCssExtractPlugin({ filename: `[name]_[contenthash:8].css`, }) ] };
再次打包,警告消失。
今天我们的课程的核心内容是理解node.js的概念,能够通过npm包管理工具进行第三方模块的安装和使用,对于webpack只要了解它的基本作用即可,随着大家的学习深入,会对webpack的理解逐渐加深。