提供一个作者自己基于 webpack
搞好的一个下载包,可以看看https://github.com/chichengyu/webpack
介绍 webpack 之前,我们先看看 nrm :
nrm 提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址;
什么是镜像:原来包刚一开始是只存在于国外的NPM服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创建一个和官网完全一样的NPM服务器,只不过,数据都是从人家那里拿过来的,除此之外,使用方式完全一样;
- 运行
npm i nrm -g
全局安装nrm
包; - 使用
nrm ls
查看当前所有可用的镜像源地址以及当前所使用的镜像源地址; - 使用
nrm use npm
或nrm use taobao
切换不同的镜像源地址;
注意: nrm 只是单纯的提供了几个常用的 下载包的 URL地址,并能够让我们在 这几个 地址之间,很方便的进行切换,但是,我们每次装包的时候,使用的 装包工具,都是 npm
网页中引入的静态资源多了以后有什么问题???
- 网页加载速度慢, 因为 我们要发起很多的二次请求;
- 要处理错综复杂的依赖关系
而webpack可以解决上面的问题,webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具。
webpack与gulp区别
- 使用Gulp, 是基于 task 任务的;
- 使用Webpack, 是基于整个项目进行构建的;
- 借助于webpack这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能。
webpack安装
- 运行
npm i(install) webpack -g
全局安装webpack,这样就能在全局使用webpack的命令(npm uninstall webpack -g卸载 )
安装指定版本
npm i webpack@3.3.0 -g - 在项目根目录中运行
npm i webpack --save-dev
安装到项目依赖中,安装webpack到项目中时的打包命令,如:
./node_modules/.bin/webpack ./src/main.js -o ./dist/bundle.js
npm install webpack@3.3.0 --save-dev
清除安装内存
cnpm cache clean
cnpm cache clean --force // 4.0以上版本注意:
1.webpack4.0以后需要加上 -o 表示--output输出的意思(如:webpack ./1.js -o ./2.js)
2.可能还需要先 npm install webpack -D(--save-dev) 安装后,才能进行打包
3.当前项目根目录还没有 package,json文件时,使用 npm init -y 就可以生成,不过需要注意的是,当前还没有安装 npm i webpack 时,必须先删除 package,json文件,当 webpack 安装后,再使用 npm init -y 生成 package.json文件,不然会报错。(如果使用了 -f(代表force)、-y(代表yes),则跳过提问阶段,直接生成一个新的 package.json 文件)
注意:4.0以上的且需要安装热替换的可以直接输入
npm install webpack webpack-cli webpack-dev-server --save-dev
一次性把需要的依赖安装完。
如果不成功,可单独安装 Webpack 开发工具
npm install webpack-dev-server --save-dev
注意:运行热替换 webpack-dev-server时,必须把webpack安装到项目依赖
为了使用方便,可以在package.json中的 scripts配置一些使用的命令如下:
"scripts":{
// 名称:值
// --open 表示运行命令就自动打开浏览器,--port 端口3000,--contentBase src 打开浏览器后自动打开根目录 src,--hot 可以使修改后的实现局部打包,同时浏览器自动刷新
"dev":"webpack-dev-server --open --port 3000 --contentBase src --hot"
}
然后在命令行直接输入 npm run dev 就执行了。(--open 表示运行命令就自动打开浏览器,--port 端口3000,--contentBase src 打开浏览器后自动打开根目录 src,--hot 可以使修改后的实现局部打包,同时浏览器自动刷新),
第二种配置方法
在配置文件中加入 devServer,如下:
// 先修改 package.json中的命令
"scripts":{
"dev":"webpack-dev-server"
}
// 在 webpack.config.js配置文件中中加入
const webpack = require('webpack');
devServer:{
open:true,// 自动打开浏览器
port:3000,// 运行端口
contentBase:'src',// 指定托管的根目录
hot:true// 启动热更新
//但是通过日志发现页面先热更新然后又自动刷新,这和自动刷新是一样的。
//如果只需要触发HMR,可以再加个参数hotOnly:true,这时候只有热更新,禁用了自动刷新功能。
//如果需要自动刷新就不需要设置热更新。
hotOnly:true// 只有热更新,禁用自动刷新功能
//服务端压缩是否开启
compress:true,
},
plugins:[
//热更新插件 new一个热更新模块对象
new webpack.HotModuleReplacementPlugin(),
]
此时,可以安装一个在内存中生成 html 页面与处理路径的插件
npm i html-webpack-plugin -D
在 webpack.config.js 配置文件中加入如下:
const htmlWebpackPlugin = require('html-webpack-plugin');
plugins:[
// 在内存中创建一个 html 页面的插件
new htmlWebpackPlugin({
// 指定模板页面,将来会根据指定的页面路径去生成内存中的页面
template:path.join(__dirname,'./src/index.html'),
// 内存中生成的页面的名称
filename:'index.html'
})
]
'html-webpack-plugin'
插件的作用:
1.自动在内存中根据指定的页面生成一个内存的页面
2.自动把打包好的 bundle.js 以正确的路径引入到页面底部,不需要我们手动处理 bundle.js 的路径。
css处理安装
包括less、scss、url路径
npm i style-loader css-loader -D
// less-loader 内部需要 依赖 less,所有需要安装 less
npm i style-loader less -D
npm i style-loader less-loader -D
// sass-loader 需要 内部依赖 node-sass,所有需要安装 node-sass
npm i style-loader node-sass -D
npm i style-loader sass sass-loader -D
// url路径 内部依赖 file-loader
npm i style-loader url-loader file-loader -D
Babel高级语法转低级
// 相当于转换工具 转换器
npm i babel-core babel-loader babel-plugin-transform-runtime -D
// 相当于语法 语法对应插件
npm i babel-preset-env babel-preset-stage-0 -D
env 是比较新的语法,包含了所有和es相关的语法
在 webpack.config.js 配置文件中加入匹配规则
module: { // 这个节点,用于配置 所有 第三方模块 加载器
rules: [ // 所有第三方模块的 匹配规则
{
test: /\.js$/, // 处理以.js结尾的文件
use:'babel-loader', //用babel-loader处理
exclude:/node_modules/ // exclude 排除,不需要编译的目录,提高编译速度(node_modules是模块安装的位置,不需要编译)
}
]
}
然后,在创建一个用于babel调用的文件,名为.babelrc,规范与json文件一样不能注释,且必须是双引号,内容如下:
{
"presets": ["env","stage-0"],
"plugins": ["transform-runtime"]
}
可以把 presets 理解成语法。
注意:在webpack打包前会,先进行 babel 转码,再打包,此时因为引入了第三方包文件,有些 js 文件会报错如下:
bundle.js:34694 Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
造成的原因可能是再引入的包中,运用了 "caller" "callee" "argusments" 这些再严格模式下不能用,而 webpack 默认启用严格模式,所以冲突了。
解决方案:1
安装一个插件,移除严格模式
// 移除严格模式插件
npm install babel-plugin-transform-remove-strict-mode
然后在 .babelrc 文件的 "plugins" 加入如下:
{
"plugins": ["transform-remove-strict-mode"],
}
表示移除 webpack 打包时的严格模式。
解决方案:2
此时,我们就需要对引入的第三方包进行忽略(意思就是 不进行转码,只打包),再 .babelrc 文件中,加入 .ignore 就是忽略的意思, 最终如下:
{
"presets": ["env","stage-0"],
"plugins": ["transform-runtime"],
"ignore":["./src/lib/mui/js/mui.min.js"]
}
我此处引入mui.min.js时,会报错上面那个严格模式错误,加入了这个,表示对这个文件 不转码,只打包,就ok了
vue包安装
npm i vue-loader vue-template-compiler -D
在 webpack.config.js 配置文件中,加入:
module:{
rules:[
{ test: /\.vue$/, use:"vue-loader"}, // 配置处理 .vue组件文件的 第三方 loader 规则
]
}
main.js入口文件
入口文件 main.js,内容如下:
// 处理 css 文件 npm i style-loader css-loader -D
import "./src/css/index.css";
// 处理 less 文件 npm i less-loader -D
import "./src/css/index.less";
// 处理 scss 文件 npm i sass-loader -D
import "./src/css/index.scss";
// 引入bootstrap font 字体文件 npm i bootstrap -S
import "bootstrap/dist/css/bootstrap.css";
webpack.config.js配置文件
在webpack.config.js对象身上,有一个model,它是一个对象,在这个对象身上,有个rules属性,这个rules属性是个数组,这个数组中存放了所有第三方文件的匹配和处理规则
为了使用方便,一般需要一个配置文件,内容如下:
const path = require('path');
// 通过node中的模块操作,向外暴露了一个配置对象
module.exports = {
mode: 'production',
entry:path.join(__dirname,'./src/main.js'),// 待打包的入口文件
output:{
path:path.join(__dirname,'./dist'),// 打包到那个目录
filename:'bundle.js'// 打包后的文件名称
},
plugins:[
//热更新插件 new一个热更新模块对象
new webpack.HotModuleReplacementPlugin(),
// 在内存中创建一个 html 页面的插件
new htmlWebpackPlugin({
// 指定模板页面,将来会根据指定的页面路径去生成内存中的页面
template:path.join(__dirname,'./src/index.html'),
// 内存中生成的页面的名称
filename:'index.html'
})
],
module: { // 这个节点,用于配置 所有 第三方模块 加载器
rules: [ // 所有第三方模块的 匹配规则
{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, // 配置处理 .css 文件的第三方loader 规则
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }, //配置处理 .less 文件的第三方 loader 规则
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, // 配置处理 .scss 文件的 第三方 loader 规则
{ test: /\.(jpg|png|jpeg|gif|bmp)$/, use: "url-loader?limit=7631&name=[hash:8]-[name].[ext]" }, // 配置处理 图片路径 文件的 第三方 loader 规则,?limit限制小于7631个字节的图片会用base64转码,name表示还是用图片原来的名称且前面加上8位的hash哈希值,防止文件名称冲突,ext还是图片原来的后缀
{ test: /\.(ttf|eot|woff|woff2)$/, use:"url-loader"}, // 配置处理 font 字体文件的 第三方 loader 规则
{ test: /\.js$/, use:"babel-loader",exclude:/node_modules/}, // 配置处理 高级语法转低级语法的 第三方 loader 规则
{ test: /\.vue$/, use:"vue-loader"}, // 配置处理 .vue组件文件的 第三方 loader 规则
]
},
resolve:{
alias:{
// 修改 vue 被导入时的路径 $ 表示以 vue 结尾
"vue$":"vue/dist/vue.esm.js",
// 给根目录下的 src 目录配置别名。方便引入文件
// 注意:在模板组件中的 <style>引入样式 需要加 ~ 波浪线
// 如:import '~@css/style.css'
"@": resolve("src")
}
}
}
__dirname 当前运行的js文件所在的目录,配置文件一般放在根目录下。
注意
1、在 vue-cli 脚手架中,当在 resolve 中设置了路径别名后,在模板组件中的 <style> 中引入样式 需要加 ~ 波浪线,如: import '~@css/style.css' 。
2、在 vue-cli 脚手架中,在模板组件中的 <style> 中的样式可以穿透子组件,不受 scoped 限制,如: .swiper >>> .swiper-action { color:red },>>>表示样式穿透,表示 .swiper 里面所有子组件,出现 .swiper-action 的都应用这个样式
真机测试
先在电脑上下载一个热点,比如:360wifi、猎豹无限wifi,然后将手机链接上热点,接着 cmd 窗口输入 ipconfig ,查看 《无限局域网 适配器 本地链接* 》这一栏,找到 《IPv4》的这个 ip地址,复制一下,然后的打开 package.json 文件,再 "dev" 后加上一项 --host 指定一下 ip(默认是localhost) 如下:
"scripts":{
// --open 表示运行命令就自动打开浏览器,--port 端口3000,--contentBase src 打开浏览器后自动打开根目录 src,--hot 可以使修改后的实现局部打包,同时浏览器自动刷新,--host 指定ip地址
"dev":"webpack-dev-server --open --port 3000 --contentBase src --hot --host 172.23.232.1"
}
此时,就可以在 手机上输入 172.23.232.1 地址就能访问到当前正在开发的项目。
webpack命令
webpack --config XXX.js //使用另一份配置文件(比如webpack.config2.js)来打包
webpack --watch //监听变动并自动打包
webpack -p //压缩混淆脚本,这个非常非常重要!
webpack -d //生成map映射文件,告知哪些模块被最终打包到哪里了