nrm 的安装和使用
作用:提供一些常用 NPM
包镜像地址,包括国内的:cnpm
、淘宝镜像,可以加快 npm
包下载速度(npm 镜像默认从国外官网下载,速度很慢)
安装:
- 安装:
npm i nrm -g
全局安装nrm
包 - 查看:
nrm ls
查看当前可以镜像源地址 - 切换:
nrm use npm
或nrm use taobao
切换不同的镜像源地址
使用演示:
# 查看所有能用的镜像源地址
$ D:软件100-编码相关cmder>nrm ls
* npm -------- https://registry.npmjs.org/
yarn ------- https://registry.yarnpkg.com/
cnpm ------- http://r.cnpmjs.org/
taobao ----- https://registry.npm.taobao.org/
nj --------- https://registry.nodejitsu.com/
npmMirror -- https://skimdb.npmjs.com/registry/
edunpm ----- http://registry.enpmjs.org/
# 切换到淘宝镜像源地址
$ D:软件100-编码相关cmder>nrm use taobao
Registry has been set to: https://registry.npm.taobao.org/
在网页中会引用哪些常见的静态资源?
- JS:
.js .jsx .coffee .ts
(TypeScript 类 C# 语言) - CSS:
.css .less .sass .scss
- Images:
.jpg .png .gif .bmp .svg
- 字体文件(Fonts):
.svg .ttf .eot .woff .woff2
- 模板文件:
.ejs .jade .vue
网页中引入的静态资源多了以后有什么问题
- 网页加载速度慢, 导致要发起很多的二次请求
- 要处理错综复杂的依赖关系
如何解决上述两个问题
- 合并、压缩、精灵图、图片的
Base64
编码 requireJS
和webpack
解决各个包之间的依赖关系
什么是webpack
webpack
是前端的一个项目构建工具,它是基于 Node.js
开发出来的一个前端工具;它可以实现资源的合并、打包、压缩和混淆等功能,也能解决各个包之间的依赖关系,比如低版本浏览器不能识别 ES6 语法,通过 webpack
转换成浏览器识别的语法。
webpack 安装
两种方式:
- 全局安装:
npm i webpack -g
,全局都可以使用webpack
命令,不推荐全局安装 - 局部安装(项目):
npm i webpack --save-dev
安装到项目依赖中 - 其他安装:
npm install webpack-cli --save-dev
初步使用
使用 webpack
打包构建列表隔行变色案例:
1、运行 npm init
初始化项目,使用 npm
管理项目中的依赖包,会生成一个 package.json
文件
2、创建项目基本结构:src
、dist
(发布)
3、安装 webpack、webpack、jQuery
npm i webpack --save-dev
npm i webpack-cli --save-dev
npm i jquery --save-dev
4、创建index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>初次使用 webpack </title>
<!-- <script src="./main.js"></script> -->
<script src="../dist/bundle.js"></script>
<!-- Uncaught SyntaxError: Cannot use import statement outside a module -->
</head>
<body>
<ul id="list">
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
<li>123</li>
</ul>
</body>
</html>
5、创建 main.js
入口文件:
// 入口 js 文件
// 导入 jQuery 类,导入 jQuery 并取名为 $
import $ from 'jquery' // ES6 才新增的语法,低版本浏览器不能识别,需要使用 webpack 转换
$(function () {
// 设置偶数行背景色,索引从 0 开始,0 为偶数
$('li:even').css('backgroundColor', 'lightblue');
// 设置奇数行背景色
$('li:odd').css('backgroundColor', function () {
return '#' + 'D97634'
});
})
import
是 ES6
才新增的语法,低版本浏览器不能识别,需要使用 webpack
转换:
6、运行 webpack 入口文件路径 输出文件路径
对 main.js
进行处理,将 main.js
转换到 dist/bundle.js
文件中,使得低版本浏览器能够支持 import
语法:
// webpack 4.x 版本
// 使用 webpack3.x 命名会报错:Module not found: Error: Can't resolve 'dist/bundle.js'
webpack .srcmain.js -o .distundle.js --mode=development
// webpack 3.x 版本
webpack .srcmain.js .distundle.js
踩坑记录
1、运行:webpack .srcmain.js -o .distundle.js --mode=development
时,报错:webpack : 无法加载文件 C:Usersdly15AppDataRoaming
pmwebpack.ps1,因为在此系统上禁止运行脚本。
解决:若要在本地计算机上运行您编写的未签名脚本和来自其他用户的签名脚本,请使用以下命令将计算机上的 执行策略更改为 RemoteSigned
- Windows 管理员模式打开
PowerShell
,执行:set-ExecutionPolicy RemoteSigned
,输入y
,回车 get-ExecutionPolicy
命令查看执行策略是否为:RemoteSigned
2、全局安装了 webpack
和 webpack-cli
,打包时报:We will use "npm" to install the CLI via "npm install -D". Which one do you like to install (webpack-cli/webpack-command):
解决:不用全局安装,项目中安装 webpack
和 webpack-cli
注意:修改文
package.json
后要重启:npm run dev
使用 webpack 配置文件简化打包命令
在上面我们使用 webpack .srcmain.js -o .distundle.js --mode=development
命令来打包文件,使得浏览器能够识别。但是当我们需要经常改动 main.js
,并能够实时查看页面变化时,这种方式就显得太繁琐了,这时就需要用到 webpack
的配置文件来简化打包命令。
1、在项目根目录创建 webpack
配置文件:webpack.config.js
2、指定运行 webpack
命令时的入口文件和输出文件路径:
var path = require('path')
module.exports = {
entry: path.join(__dirname, './src/main.js'), //入口文件
output: {
// 输出选项
path: path.join(__dirname, './dist'), // 输出路径
filename: 'bundle.js', // 指定输出文件名称
},
}
项目目录结构
dist
- bundle.js
node_modules
src
- css
- images
- js
- index.html
- main.js
package.json
webpack.config.js // webpack 配置文件
配置完毕后,就可以使用 webpack
命令来打包。
webpack-dev-server 实现实时打包
每次重新修改代码后,都需要手动运行 webpack
命令,比较麻烦,可以不使用 webpack-dev-server
插件来实现代码实时打包编译,
当修改代码后,它会自动进行打包构建。
1、安装到项目依赖:
npm i webpack-dev-server --save-dev
2、借助 package.json
的 Scripts
节点来指定打包指令:
{
"name": "day05",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"dev": "webpack-dev-server --open --port 3000 --hot" // 新增
},
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.4.1",
"webpack-dev-server": "^3.10.3"
},
"devDependencies": {
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11"
}
}
webpack-dev-server 会将打包编译的 bundle.js
文件放在 内存,而不是 dist/
目录下,这也是它为什么能
快速打包编译的原因。
3、运行 npm run dev
命令,直接打开浏览器跳转到 http://localhost:3000
(默认 8080) 访问到首页。也可以使用 --contentBase src
参数来指定启动目录:
"dev": "webpack-dev-server --contentBase src"
4、修改 index.html
中的 bundle.js
引入路径:
// 此刻的 bundle.js 不在 dist 目录中,而是在内存中,这里使用的是相对路径
<script src="/bundle.js"></script>
// 原先
<script src="../dist/bundle.js"></script>
至此所有的配置都已完成,当我们修改 main.js
文件时,webpack-dev-server
就会自动帮我们实时打包编译,不需要再手动执行打包编译命令。
注意:修改 package.js 后需要重启,命令:npm run dev
webpack-dev-server 两种配置方式
package.json
:"dev2": "webpack-dev-server --open --port 3000 --hot --contentBase src",
webpack.config.js
:配置参数,package.json
中配置命令
1、package.json
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
// "dev2": "webpack-dev-server --open --port 3000 --hot --contentBase src",
"dev": "webpack-dev-server" // 命令
},
2、webpack.config.js
var path = require('path')
// 启用热更新第 2 步
const webpack = require('webpack')
module.exports = {
entry: path.join(__dirname, './src/main.js'), //入口文件
output: {
// 输出选项
path: path.join(__dirname, './dist'), // 输出路径
filename: 'bundle.js', // 指定输出文件名称
},
devServer: {
// 配置 webpack-dev-server 的第二种方式
open: true, // 自动打开浏览器
port: 3000,
contentBase: 'src', // 指定托管的根目录
hot: true // 启用热更新第 1 步
},
plugins: [
new webpack.HotModuleReplacementPlugin() // new 一个热更新的模块对象,启动热更新
]
}
注意:此种方式不推荐使用!
html-webpack-plugin 插件配置启动页面
由于使用 --contentBase
指令过于繁琐,需要指定启动的目录,还需要修改 index.html
中 script
标签的 src
熟悉,推荐使用 htm-webpack-plugin
来启动页面。
作用:
- 自动在内存中根据指定页面生成一个内存的页面
- 自动把打包好的
bundle.js
追加到页面中去
在内存中生成 HTML
页面
当使用 html-webpack-plugin
之后,就不再需要手动处理 bundle.js
的引用路径了,它会帮我们自动创建一个合适的 script
,并引用正确的路径。
1、安装:npm i html-webpack-plugin --save-dev
2、修改 webpack.config.js
配置文件如下:
var path = require('path')
// 启用热更新第 2 步
const webpack = require('webpack');
// 导入:html-webpack-plugins
var htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.join(__dirname, './src/main.js'), //入口文件
output: {
// 输出选项
path: path.join(__dirname, './dist'), // 输出路径
filename: 'bundle.js', // 指定输出文件名称
},
devServer: {
// 配置 webpack-dev-server 的第二种方式
open: true, // 自动打开浏览器
port: 3000,
contentBase: 'src', // 指定托管的根目录
hot: true // 启用热更新第 1 步
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // new 一个热更新的模块对象,启动热更新
// 所有 webpack 插件的配置节点
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
filename: 'index.html' // 设置生成内存页面的名称
})
]
}
先导入 html-webpack-plugins
插件,再在 plugins
数组中配置相应模板文件路径和名称。
3、修改package.json
中script
节点中的dev指令如下:
"dev": "webpack-dev-server"
4、可以将 index.html
中的 script
注释掉,因为 html-webpack-plugins
会自动引用,查看网页源代码:
webpack 打包 css、less 和 sass 文件
使用 link 标签引用 css、less、sass 等文件时会发送二次请求,可以在 main.js 中 import
webpack
默认只能打包处理 js
文件,无法处理其他类型文件,若想处理其他类型文件需要安装第三方 loader
webpack 处理第三方文件类型过程
- 发现要处理的文件是非
js
文件,就去配置文件中查找有没有对应的第三方loader
规则 - 若有
loader
规则,则调用,否则编译失败 - 调用顺序,从后往前
- 当最后一个
loader
调用完毕后,会将处理结果交给webpack
进行打包合并,并最终输出到bundle.js
打包 css 文件
1、新建 css/index.css
:
li {
list-style: none;
}
2、在 main.js
中进行引用:
// 入口 js 文件
// 导入 jQuery 类,导入 jQuery 并取名为 $
import $ from 'jquery'
import './css/index.css' // 引用 css 文件
$(function () {
// 设置偶数行背景色,索引从 0 开始,0 为偶数
$('li:even').css('backgroundColor', 'yellow');
// 设置奇数行背景色
$('li:odd').css('backgroundColor', function () {
return '#' + 'D97634'
});
})
3、安装 cnpm i style-loader css-loader --save-dev
4、修改 webpack.config.js
:
module.exports = {
plugins: [
new webpack.HotModuleReplacementPlugin(), // new 一个热更新的模块对象,启动热更新
// 所有 webpack 插件的配置节点
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
filename: 'index.html' // 设置生成内存页面的名称
})
],
// 配置第三方模块加载器 loader
module: {
rules: [
// test: 正则匹配,点需要转义,这里是匹配以 .css 结尾的文件
{ test: /.css$/, use: ['style-loader', 'css-loader'] },
]
}
}
打包 less 文件
1、新建 css/index.less
:
ul {
padding: 0;
margin: 0;
}
2、在 main.js
中进行引用:
// 入口 js 文件
// 导入 jQuery 类,导入 jQuery 并取名为 $
import $ from 'jquery'
import './css/index.css' // 引用 css 文件
import './css/index.less' // 引用 less 文件
$(function () {
// 设置偶数行背景色,索引从 0 开始,0 为偶数
$('li:even').css('backgroundColor', 'yellow');
// 设置奇数行背景色
$('li:odd').css('backgroundColor', function () {
return '#' + 'D97634'
});
})
3、安装 cnpm i less-loader less -D
4、修改 webpack.config.js
:
module.exports = {
plugins: [
new webpack.HotModuleReplacementPlugin(), // new 一个热更新的模块对象,启动热更新
// 所有 webpack 插件的配置节点
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
filename: 'index.html' // 设置生成内存页面的名称
})
],
// 配置第三方模块加载器 loader
module: {
rules: [
// test: 正则匹配,点需要转义,这里是匹配以 .css 结尾的文件
{ test: /.css$/, use: ['style-loader', 'css-loader'] },
{ test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
]
}
}
打包 sass 文件
1、新建 css/index.scss
:
html, body{
margin: 0;
padding: 0;
li{
font-size: 12px;
line-height: 30px;
}
}
2、在 main.js
中进行引用:
// 入口 js 文件
// 导入 jQuery 类,导入 jQuery 并取名为 $
import $ from 'jquery'
import './css/index.css' // 引用 css 文件
import './css/index.less' // 引用 less 文件
import './css/index.scss' // 引用 scss 文件
$(function () {
// 设置偶数行背景色,索引从 0 开始,0 为偶数
$('li:even').css('backgroundColor', 'yellow');
// 设置奇数行背景色
$('li:odd').css('backgroundColor', function () {
return '#' + 'D97634'
});
})
3、安装 cnpm i sass-loader node-sass --save-dev
4、修改 webpack.config.js
:
module.exports = {
plugins: [
new webpack.HotModuleReplacementPlugin(), // new 一个热更新的模块对象,启动热更新
// 所有 webpack 插件的配置节点
new htmlWebpackPlugin({
template: path.join(__dirname, './src/index.html'), // 指定模板文件路径
filename: 'index.html' // 设置生成内存页面的名称
})
],
// 配置第三方模块加载器 loader
module: {
rules: [
// test: 正则匹配,点需要转义,这里是匹配以 .css 结尾的文件
{ test: /.css$/, use: ['style-loader', 'css-loader'] },
{ test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
{ test: /.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
]
}
}
处理 CSS 中 URL 地址
webpack
无法处理 css
文件中的 URL
地址,不管是图片还是字体库,都不能处理,需要采用第三方 loader
:url-loader、file-loader
。
1、新增 index.html
:
<div class="box">
</div>
2、修改 css/index.scss
:
html, body{
margin: 0;
padding: 0;
li{
font-size: 12px;
line-height: 30px;
}
.box {
220px;
height: 120px;
background: url('../images/生小孩.jpg');
background-size: cover;
}
}
3、安装:cnpm i url-loader file-loader --save-dev
4、webpack.config.js
:
// 配置第三方模块加载器 loader
module: {
rules: [
// test: 正则匹配,点需要转义,这里是匹配以 .css 结尾的文件
{ test: /.css$/, use: ['style-loader', 'css-loader'] },
{ test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
{ test: /.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
// 处理 css 中 url 地址
{ test: /.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7630' }
]
}
参数
webpack
处理图片,图片地址默认为 base64
,若不想以 base64
显示,可以配置相应参数:
limit
: 给定的值为图片的字节大小(byte
),若大于图片大小,则会转换为base64
,小于或等于则不会(哈希值)name
:若想使用图片原有名称,可以使用name
参数,用法:{ test: /.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7630&name=[name].[ext]' }
,其中.[ext]
为固定写法
当有两张名称相同,但所属不同目录的图片,分别被 HTML
引用时,且都使用的图片原名称;webpack
打包后,页面只会显示其中一张图片。
解决办法:
// 在 [name] 之前添加一个 [hash:8]-,表示将图片名称进行哈希,并只取前 8 位
{ test: /.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7631&name=[hash:8]-[name].[ext]' },
处理 ttf、svg 等字体文件
也是使用 url-loader
处理字体文件,以下以 Bootstrap
样式中的字体文件为例:
1、index.html
:
<span class="glyphicon glyphicon-heart" aria-hidden="true"></span>
2、安装 cnpm i bootstrap -S
3、引入 Bootstrap
,main.js
:
import 'bootstrap/dist/css/bootstrap.css'
安装的第三方包在 node_modules/
文件夹中,引入时可省略 node_modules
前缀
4、webpack.config.js
:
// 配置第三方模块加载器 loader
module: {
rules: [
// 处理字体文件
{ test: /.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' },
]
}
使用 babel 处理高级 JS 语法
webpack
默认只能处理一部分 ES6
的新语法,一些更高级的或者 ES7
语法无法处理;需要借助第三方 loader
来处理,它们可以将高级语法转换为低级语法,把结果交给 webpack
去打包。
1、main.js
中新增:
class Person {
// 静态方法
static info = { name: 'zs', age: 18 }
}
console.log(Person.info)
class Person
是 ES6
中的语法,webpack
处理不了,需要借助:babel-loader
来处理。
2、安装:
cnpm i babel-core babel-loader babel-plugin-transform-runtime -D
cnpm i babel-preset-env babel-preset-stage-0 -D
// 为保证运行不会出错,babel 各个版本与示例中尽量保持一致,高版本可能不会生效
cnpm i babel-core@6.26.0 babel-loader@7.1.2 babel-plugin-transform-runtime@6.23.0 -D
cnpm i babel-preset-env@1.6.1 babel-preset-stage-0@6.24.1 -D
3、webpack.config.js
新增 rules
匹配规则:
{ test: /.js$/, use: 'babel-loader', exclude: /node_modules/ }, // exclude:排除 node_modules 目录中的 js 文件
注意:
babel-loader
会将高级 JS 语法转换为低级 JS 语法,涉及到的文件只有main.js
,不包括node_module/
中的 JS,因此需要将其排除掉,否则也会将node_modules/
中的 JS 文件打包编译,会消耗CPU
,同时打包速度会非常慢。
4、项目根目录新建:.babelrc
文件:
{
"presets": ["env", "stage-0"],
"plugins": ["transform-runtime"]
}
注意:该文件为
json
格式文件,必须符合json
格式语法
参考文章