- grunt/gulp/webpack/rollup(vue源码是由rollup构建的)
什么是webpack
- webpack是一个现代的JavaScript应用的静态模块 打包工具
- 目前使用前端模块化的一些方案:AMD,CMD,Commonjs,ES6,但是目前只有Es6浏览器有底层支撑,在webpack里面就可以使用,会进行一些转换,打包里面没有原来你写的代码
- 进行模块话开发,并且帮我们处理模块间的依赖关系
- WebPack是前端资源模块工具,主要分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
和grunt、gulp的对比
- grunt、gulp的核心是task,定义任务流,配置一系列的task,并且定义task要处理的事务(例如ES6,图片压缩),之后让grunt、gulp来执行这些任务,让整个流程自动化,所以grunt、gulp也被称为前端自动化任务管理工具
- webpack为了可以正常运行,必须依赖node环境,node环境为了可以正常的执行很多代码,必须其中包含各种依赖的包,手动管理的话很难,所以有一个npm工具来帮助我们管理(node packages manager)
win + r 打开终端
node -v 检查node环境版本
npm install [email protected] -g 全局安装3.6.0这个版本的webpack
webpack --version 检查webpack版本
cd 对应目录
为什么全局安装后,还需要局部安装呢
-
在终端直接执行webpack命令,使用的全局安装的webpack
-
当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部的webpack
-
这里因为main.js依赖了其他文件,所以写一个,webpack会自动处理
-
WebPack的优点:
模块化,可以组织管理很多细化为小的资源文件,将它们合并打包。
ES6规范支持,类似TypeScript是在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能转换为JavaScript文件使浏览器可以识别。Scss,less等CSS预处理器。
webpack的基本使用过程
- 我们采用原来的东西相出传的时候,两个js文件,一个传到一个,一个用,在index里面引用一个,但是这一个文件还依赖了另一个文件,不行,一个一个引用非常麻烦,所以使用打包工具,在这里,我们可以使用如下webpack工具,如下,这样,就在dist的下面建了一个js文件,引用这个js文件,就行
- 在scripts这里想用什么模块化(commonjs,es6等)就用什么模块化开发,webpack就会打包,将多个js打包到一个js文件中,引入就变得方便了
- 打包一个东西放到index里面
- 原码(src)
- 打包到dist(dist->distribution发布)
- 在其他js文件写入原来函数并导出,在main.js里面导入,进行使用
- 按下cd要进入一个文件夹时,tab键可以自动补全
webpack ./src/main.js ./dist/bundle.js,后面可以直接使用webpack进行打包,也可以使用npm run build 利用webpack将我们的前面那个文件打包到dist下面的bundle.js里,这里bundle是自动生成的文件,
这里出现了l两个问题,就是Uncaught ReferenceError: re is not defined at Object.<anonymous> (bundle.js:,原因是多了一个re,because its MIME type ('application/octet-stream') is not executable, and st,原因是js的s大写了
js打包
入口和出口的配置–package.json
-
cd .. 返回上一级
-
./ 同级目录
-
/ 根目录
-
npm init进行初始化,任何一个项目,如果你想单独依赖我们一些node环境的话,一般情况下,通过改命令我们都会有package.json这个文件,这个文件是告诉我们当前项目的一些信息的,例如:版本号,名字......
-
npm install当我们的package.json里面还依赖一些东西话,可以根据我们package.json里面的所有依赖,在当前文件夹里安装一些东西
-
只有开源里面才需要这个package.json的"license": “ISC”
const path = require('path')
//依赖我们的node包,建好package.json文件,通过require导出我们这个path包
//他会从我们的node包里面去找path,不是当前目录,但是我们现在没有,所以我们要进行一个初始化
module.exports = {
entry:'./src/main.js',
//入口
output:{
// path:'./dist',
//这里应该写一个绝对路径,这种写法不对
path:path.resolve(__dirname,'dist'),
//对两个路径进行拼接,__dirname是node的一个全局变量,获得当前文件所在目录的完整路径
//这个路径是一个绝对路径
filename:'bundle.js'
//bundle打包的意思
},
// 出口
}
1,创建webpack.config.js文件,目前这个名字不可更改,写入导入导出,这个文件配置好以后,我们可以通过webpack直接进行打包
2,npm init然后生成package.json文件
3,导入本地包 npm installn webpack @3.6.0 --save-dev
局部安装webpack
-
把npm run build映射webpack,以后会很长,当我们把webpack.config这个名字webpack改了haha之后,还要使用webpack.haha,很麻烦,在前面那个文件加上build:webpack,在输入npm run build一样
-
将webpack和npm run build映射起来
-
这里执行这个命令还跟直接写webpack不一样,写到package.json文件里面会优先在本地去找我们这个命令,即使用npm run build
-
npm install [email protected] --save-dev 本地安装webpack 开发时依赖
-
开发阶段才需要这个东西,项目运行时不需要,webpack就是在打包之后就没有用的东西,所以加上一个–save-dev开发时依赖devDependencies
-
运行时依赖
-
只要是在终端里敲命令的,就会是全局webpack帮我们打包,两个终端,但是定义一个脚本,会优先在本地里找,即本地的node_modules/.bin,如果没找到,会去全局的环境变量中寻找,就想用运用webpack局部的,一层一层找./node_modules/.bin/webpack
css打包
使用css文件的配置
什么时loader
- webpack打包的时候只会根据我们的入口依次去找,就会找到main.js,会根据依赖一层一层找,然后我们需要依赖css
require('./css/normal.css') 在 main.js里依赖我们css
- .org非盈利性组织
- 给webpack扩展对应的loader
使用过程
-
1,通过npm安装使用的loader
-
npm install --save-dev css-loader 这个只负责加载,不负责解析,所以页面没有渲染出来
-
npm install style-loader --save-dev 负责将样式添加到DOM中
-
npm uninstall css-loader 卸载已经安装的css-loader
-
npm config set registry https://registry.npm.taobao.org 安装lessverb npm-session 092a5590abdd61da,更换npm园,淘宝镜像
-
在这里要注意版本号问题,我们可以在package.json文件里直接修改版本号,然后执行命令npm install
-
在webpack.config.js中的modules关键字下进行配置
//bundle打包的意思
},
// 出口
module:{
rules: [
{
//匹配.css文件
test: /\.css$/,
//使用多个loader时,是从右向左
use: [ 'style-loader', 'css-loader' ]
}
]
}
}
//3 .依赖css文件
require('./css/normal.css')
less打包
less文件的处理
npm install --save-dev less-loader less 这个less也可以作为npm里面的一个包,这个可以最终对我们的less文件进行解析,前面只是负责加载的,后面这个less才是负责将我们less进行转换的
- 这里注意版本号,我们也可以使用npm install进行修改
//4 依赖less文件
require('./css/special.less')
document.writeln('<h2>你好啊</h2>');
//和document.write不一样的是上面的这个会换行
配置:
module: {
rules: [
{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}
]
}
}
SyntaxError: Unexpected end of input 他通常表示我们浏览器在读取我们的js代码时,碰到了不可预知的错误,导致浏览器 无语进行下面的读取 通常造成这种错误的原因是应该成双的符号输入错误,比如说“”,‘’,{},[]。
图片打包
图片文件的处理
- png要比jpg图片要大
npm install --save-dev url-loader 安装1.1.2
{
//在早期的dos系统里,任何文件的后缀名只允许存在三个,
// 后来Windows,Linux操作系统,就支持很多,所以,jpg和jpeg没有太大区别
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 18432
//这里的limit限制上传大小,当我们的图片是17kb,然后要乘以1024进行换算
}
}
]
- 当加载的图片,小于limit时,会将图片编译成base64字符串形式
- 当我们加载的图片大于limit时,会使用file loader对我们的图片进行加载,file loader我们只需要安装一下,大于当成一个完整的图片,要进行打包,把这张图片打包到我们的dist文件夹里,将来连同我们的bundlejs一起发布,但是这时候我们的页面并没有渲染出来,在我们的dist文件夹里已经有了原来的图片,并且通过哈希自动生成,32位,目的是为了防止它重复,这时候,我们将展示的是打包后的图片,相当于加载当前文件夹下面的这个文件,但是位置不对
- 原来没有./dist,只要说是我们加上./dist,他就能正常显示了,这里我们需要改一个配置
publicPath:'dist/ 只要涉及到url的东西,他就会在前面加上一个dist/'
npm install file-loader --save-dev 安装file loader--save-dev可以写到file loader的前面或者后面
- 当我们把index.html放到dist文件夹里面,就不用 publicPath:'dist/
对图片进行相关命名
- 我们图片放的很乱这样的话,我们可以通过如下方法进行配置
limit: 11264,
name:'img/[name].[hash:8].[ext]'
//当我们这里直接写上name时,他最后会打包出来的文件就叫name,相当于一个固定的名字,
// 而加上中括号的话,就相当于是一个变量,原来是啥名字就是啥名字
}
}
- npm run build 在dist文件夹下生成了img文件夹,然后文件夹里放着我们的图片,命名是我们原来的名字夹加8的hash值
ES6打包
ES6转ES5的bable
- webpack打包的js文件,发现写的ES6语法并没有转成 ES5,我们现在就是想让我们的bundle.js里面全部是ES5
npm install babel-loader babel-core babel-preset-env 这里使用ES2015版本会进行报错,但是可以先装这个版本,然后在package.json文件里面改,注意改配置presets
配置:
{
test: /\.js$/,
exclude:排除
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
打包vue
使用VUE的配置过程
- 我们以前都是通过直接下载下来vue.js,然后进行引用,然后开始写代码
npm install vue --save 安装vue,并不是开发时依赖,所以我们这个后面并没有-dev,这里也可以写一个-S,也表示--save
//5 使用vue进行开发,进行依赖
import Vue from 'vue'
const app = new Vue({
el:'#app',
data:{
message:'hello'
}
})
body>
<div class="app">
<h2>{{message}}</h2>
</div>
<scr
- vue在构建最后发布版本的时候,它构建了两类版本。一类叫runtime-only,使用这个的话,我们的代码中,不能有任何的template,这里会将index里的
<div class="app"><h2>{{message}}</h2></div>
叫做vue实例的template,一类叫runtime-compiler可以有template,因为有compiler可以用于编译template - 这里老师是会报错,但是因为版本不同,我们的会出现{{message}},然后我们进行配置webpack.config.jsresolve
_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
},
resolve:{
//alias:别名
alias:{
'vue$':'vue/dist/vue.esm.js'
//将vue指向一个具体的文件夹,不会是默认的路径
}
}
vue和template和el的关系
- SPA(single page web application)单页面复应用,我们一般只有一个HTML代码,多个页面,我们是通过路由跳转的–vue-router(前端路由)
- 我们不改index里面的代码,HTML模板我们不希望手动的频繁修改,我们又需要刚才的h2
- 当我们同时有template又有el,vue内部会自动将我们template里的代码替换
<div id="app"></div>
会将el的东西替换掉的
index里
<body>
<div id="app">
</div>
- 正常显示
vue的终极使用方案
1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
</div>
<script src="dist/bundle.js"></script>
</body>
</html>
//5 使用vue进行开发,进行依赖
import Vue from 'vue'
const App = {
template:`
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按钮</button>
<h2>{{name}}</h2>
</div>
`,
data(){
return {
message:'hello',
name:'xingxing'
}
},
methods:{
btnClick(){
}
}
}
new Vue({
el:'#app',
//这里template会替换el,在替换之前也会进行编译
template:`<App/>`,
components:{
App
}
})
2
import Vue from 'vue'
import App from './vue/app'
new Vue({
el:'#app',
template:`<App/>`,
components:{
App
}
})
export default {
template:`
<div>
<h2>{{message}}</h2>
<button @click="btnClick">按钮</button>
<h2>{{name}}</h2>
</div>
`,
data(){
return {
message:'hello',
name:'xingxing'
}
},
methods:{
btnClick(){
}
}
}
3
//5 使用vue进行开发,进行依赖
import Vue from 'vue'
import App from './vue/App'
new Vue({
el:'#app',
template:`<App/>`,
components:{
App
}
})
<template>
<div>
<h2 class="title">{{message}}</h2>
<button @click="btnClick">按钮</button>
<h2>{{name}}</h2>
</div>
</template>
<script>
export default {
name: "App",
data(){
return {
message:'hello',
name:'xingxing'
}
},
methods:{
btnClick(){
}
}
}
</script>
<style scoped>
.title{
color: burlywood;
}
</style>
- 第三种会报错,原因是不认识这个文件,我们应该配置相应的loader
npm install --save-dev vue-loader vue-template-compiler 安装两个loader
- 这里也要注意版本
- 我们可以以后写其他的组件,直接在一个组件里引用并注册
这里改一个配置,就可以省掉后缀名文件.vue
resolve:{
//alias:别名
extensions:['.js','.css','.vue'],
//写这个
alias:{
'vue$':'vue/dist/vue.esm.js'
在这里不写.vue会显示不出来颜色 import App from './vue/App.vue'
把components写错导致组件加载不出来
webpack- 横幅Plugin的使用
- loader对某些文件,进行转换和加载
- 百度与react,后来react也将协议改成MIT,意味着更加的开放了
BannerPlugin
- webpack自带的插件,为打包的文件添加版权声明
- 按照下面方式修改webpack.config.js
- 配置
- 结果
weebpack-HtmlWebpackPlugin的使用
- shift + 字母就是大写
- 查找东西 ctrl + f
- 截屏 win+shift +s alt+a
- ctrl+shift+s copy文件
npm install html-webpack-plugin --save-dev 安装HtmlWebpackPlugin
配置;
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins:[
new webpack.BannerPlugin('最终版权归aaa所有'),
new HtmlWebpackPlugin()
]
}
- 现在就会在我们的dist文件夹里生成一个index页面,现在我们还需要解决两个问题,一个是我们需要生成一个
<div id="app"></div>
,在一个我们就不需要src="dist/bundle.js"
这里的dist了,还有之前配置的那个dist路径,来将publicPath:'dist/'
注释掉 - 按如下方式,就会生成一个
<div id="app"></div>
new HtmlWebpackPlugin({
template: 'index.html'
}
webpack-UglifyjsWebpackPlugin的使用
npm install [email protected] --save-dev
配置
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
template: 'index.html'
}),
new UglifyjsWebpackPlugin()
]
- 压缩后的文件
webpack-dev-server搭建本地服务器
-
服务器先放到内存里,然后执行npm run build 才会放到硬盘里,因为磁盘读取速度远远小于内存
-
让浏览器自动刷新
-
npm install [email protected] --save-dev 这里的版本和webpack有一定的联系,安装
开发阶段需要做的一个配置
devServer:{
contentBase:'./dist',
// 这里指定我们要服务的文件夹
inline:true
// 这里表示我们需要实时监听
}
}
webpack-dev-server 通过这个运行
- 这里会报错,因为我们就在全局没有安装,我们没有加-g,不是在全局安装的,我们可以
- 下面这个是错误的
./node_modules/.bin/webpack-dev-server 我们可以指定路径
我们可以配置一个脚本来简单实现,在这里执行会优先在本地找,执行npm run dev就行,通过端口号进入,当我们把那个东西删掉之后,页面会自动进行刷新
"scripts": {
"dev": "webpack-dev-server"
},
- 测试完成之后,我们就可以直接执行一个npm run build来进行打包
ctrl + c终止命令
- 我们希望可以直接打开页面,不用我们再去点那个链接,我们可以在配置哪里写上如下配置,
"scripts": {
"dev": "webpack-dev-server --open"
},
- new UglifyjsWebpackPlugin()这里我们建议不要压缩,打包过程需要用到的配置
- alt + tab键,显示最近浏览界面
webpack配置文件的分离
- 有些东西我们是打包的时候才需要,有些东西我们是运行的时候才需要,这时候我们需要进行文件分离
- 基本的放到base里,
- 开发的放到dev里,
- 生产时特殊的放到prod里
npm install webpack-merge --save-dev 对文件进行合并
- 我们将一个文件拆成三个文件,格式如下
例如:dev.config.js
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpackMerge(baseConfig,{
devServer:{
contentBase:'./dist',
// 这里指定我们要服务的文件夹
inline:true
// 这里表示我们需要实时监听
}
})
- 现在我们就不需要webpack.config.js文件了,但是我们删了会报错,因为它默认只会找我们这个文件,所以当我们将那个文件删除之后,我们需要手动增添路径
"build": "webpack --config ./build/prod.config.js",
"dev": "webpack-dev-server --open --config ./build/dev.config.js"
- 这里会在build文件夹里建一个文件夹叫做dist
path: path.resolve(__dirname, 'dist'), 因为我们这里是当前目录,所以我们应该修改成../dist,我们就可以正常创建文件所在位置了