认识webpack
- 什么是webpack?
是前端模块化打包工具,必须依赖node环境。 - 前端模块化
目前使用前端模块化的一些方案:AMD、CMD、CommonJS、ES6。
webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用。
这就是webpack中模块化的概念。 - 打包
就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。 - 和grunt/gulp的对比
①什么时候用grunt/gulp呢?
• 如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。
• 只需要进行简单的合并、压缩,就使用grunt/gulp即可。
• 但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的webpack了。
②所以,grunt/gulp和webpack有什么不同呢?
• grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
• webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。
webpack安装
安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm
- 查看node版本
node -v
- 全局安装webpack(这里先指定版本号3.6.0,因为vue cli2依赖该版本)
npm install webpack@3.6.0 -g //-g是全局安装的意思
- 局部安装webpack(后续才需要)
–save-dev是开发时依赖,项目打包后不需要继续使用的
cd 对应目录
npm install webpack@3.6.0 --save-dev
为什么全局安装后,还需要局部安装呢?
• 在终端直接执行webpack命令,使用的全局安装的webpack
• 当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack
webpack起步
- 准备工作
文件和文件夹解析:
• dist文件夹:用于存放之后打包的文件
• src文件夹:用于存放我们写的源文件
• main.js:项目的入口文件。具体内容查看下面详情。
• math.js:定义了一些数学工具函数,可以在其他地方引用,并且使用。具体内容查看下面的详情。
• index.html:浏览器打开展示的首页html
• package.json:通过npm init生成的,npm包管理的文件(暂时没有用上,后面才会用上) - JS文件的打包
如果直接在index.html引入这两个js文件,浏览器并不识别其中的模块化代码;真实项目中当有许多这样的js文件时,我们一个个引用非常麻烦,并且后期非常不方便对它们进行管理。
我们可以使用webpack工具,对多个js文件进行打包
• webpack就是一个模块化的打包工具,所以它支持我们代码中写模块化,可以对模块化的代码进行处理
• 如果在处理完所有模块之间的关系后,将多个js打包到一个js文件中,引入时就变得非常方便了
webpack ./src/main.js ./dist/bundle.js //main里面导入了math的文件
<script src="dist/bundle.js"></script>
webpack配置
- 配置入口和出口
①在根目录下创建一个webpack.config.js文件
②在文件中输入代码(没写好的)
const path = require('path') //依赖包
module.exports = {
//入口:可以是字符串/数组/对象
entry: './src/main.js',
//出口:通常是一个对象,里面至少包含path和filename两个重要的属性
output: {
path: '', //通常是一个绝对路径,需要动态获取路径
filename: 'bundle.js'
}
}
③npm init //初始化
生成了package.json
④npm install //安装package.json的依赖
⑤修改path路径代码(写好的)
const path = require('path') //通过导入node里面全局的path依赖包
module.exports = {
//入口:可以是字符串/数组/对象
entry: './src/main.js',
//出口:通常是一个对象,里面至少包含path和filename两个重要的属性
output: {
path: path.resolve(__dirname, 'dist'), //通常是一个绝对路径,需要动态获取路径
filename: 'bundle.js'
}
}
⑥配置打包命令npm run build //将webpack命令和npm run build命令映射起来(没成功,还要下面的配置)
在package.json的scripts中定义自己的执行脚本
script中添加"build": "webpack"
- 局部安装webpack
需要在本地局部再次安装webpack(因为我们使用的webpack是全局的webpack,任何时候开发项目都有自己局部的webpack)
开发时依赖 --save-dev
npm install webpack@3.6.0 --save-dev
- package.json中定义启动
首先,会寻找本地的node_modules/.bin路径中对应的命令,如果没有找到就会去全局找。
第六步添加好了之后就可以执行npm run build
css-loader的使用
①建好css文件,在入口main.js文件中导入normal.css
require('./css/normal.css')
②通过npm安装需要使用的css-loader和style-loader,需要指定版本
npm install css-loader@2.0.2 --save-dev
npm install style-loader@0.23.1 --save-dev
css-loader 只负责将css进行加载
style-loader 将模块导出的内容作为样式并添加到 DOM 中
③在webpack.config.js中的modules关键字下进行配置
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"], //从右向左读
},
],
},
④运行npm run build
less文件处理
less的最大特点是能够进行嵌套,按照页面的业务逻辑逐层渲染,简化操作。
①创建less文件,定义字体大小和字色和背景色的变量@fontSize:50px
,使用body{ font-size: @fontSize; }
②在入口main.js文件中引用less文件require(’./css/normal.less’),打包会报错(需要对应的loader处理文件类型)
③通过npm安装需要使用的less-loadernpm install --save-dev less-loader@4.1.0 less@3.9.0
④在webpack.config.js中的modules关键字的rules下进行配置
直接在rules里面的对象下面添加
{
test: /\.less$/i,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "less-loader",
},
],
}
⑤添加html代码
在main.js中的require下面添加
document.writeln('<h2>你好啊</h2>>')
⑥运行npm run build
图片文件处理
①建好img文件,在css中引入背景图
②通过npm安装需要使用的url-loader和file-loader
npm install --save-dev url-loader@1.1.2
npm install file-loader@3.0.1 --save-dev
③在webpack.config.js中的modules关键字的rules下进行配置
limite:图片大小*1024,这是limit属性的作用,当图片小于48kb时,对图片进行base64编码
如果图片大于48kb,图片不显示出来,默认情况下,webpack会将生成的路径直接返回给使用者,但是,我们整个程序是打包在dist文件夹下的,所以这里我们需要在路径下再添加一个dist/
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 55000,
},
},
],
}
//后面的file-loader不需要配置,配了图片会不显示
④图片无法加载,报错显示路径不对,在webpack.config.js中的output关键字下进行配置
publicPath: 'dist/'
⑤修改图片名称,在webpack.config.js中的url-loader的option关键字下进行配置
name: 'img/[name].[hash:8].[ext]'
ES6语法处理
①通过npm安装babel
npm install --save-dev babel-loader@7.1.5 babel-core@6.26.3 babel-preset-es2015@6.24.1
②在webpack.config.js中的modules关键字的rules下进行配置
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
webpack配置vue
- 配置vue
①通过npm安装vuenpm install vue@2.5.21 --save
②在main.js中添加
//使用vue进行开发
import Vue from 'vue'
new Vue({
el: '#app',
data: {
message: 'hello vue'
}
})
③报错原因
报错说我们使用的是runtime-only版本的Vue
runtime-only:代码中,不可以有任何的template
runtime-compiler:代码中,可以有template,compiler可以用于编译template
解决方案:Vue不同版本构建
④在webpack.config.js添加resolve,与module平级
resolve: {
alias:{
'vue$': 'vue/dist/vue.esm.js'
}
}
- el和template区别
el和template模板的关系是什么呢?
• 在我们之前的学习中,我们知道el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。
• 而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板。 - Vue组件化开发引入
①修改main.js的,注册组件
//使用vue进行开发
import Vue from 'vue'
const App = {
template:`
<div>
<h2>{{message}}</h2>
<p>{{name}}</p>
</div>
`,
data(){
return {
message: 'hello vue',
name: 'tutu'
}
}
}
new Vue({
el: '#app',
template: '<App/>', //#app的html代码会被这个组件替换
components: { //注册组件
App
}
})
②创建vue文件
第一:新建vue文件夹,在里面新建app.js和App.vue。
第二:在app.js中输入export default,把main.js中的const App = 后面的东西剪切过来。
第三:把main.js中的const App = 删除,改成import App from './vue/app'
第四:把app.js中的templat和data分别复制到App.vue中
第五:把import App from './vue/app'
改成import App from './vue/App.vue'
- vue文件封装处理
①通过npm安装vue-loader和vue-template-compiler(编译vue)
npm install vue-loader@15.4.2 vue-template-compiler@2.5.21 --save-dev
②在webpack.config.js中的modules关键字的rules下进行配置
{
test: /\.vue$/,
use: ['vue-loader']
}
//加完这里运行后会报错,提示版本过高、缺少插件,可以安装插件,也可以去package.json中修改vue-loader版本为"vue-loader": "^13.0.0",重新npm install
③在里面嵌套vue
第一:新建一个vue,填好内容
第二:在App.vue的js中添加import Cpn from './Cpn.vue'
第三:在App.vue的template中添加<Cpn></Cpn>
④配置简写,webpack.config.js中的resolve关键字下进行配置,与alisa平级extensions: ['.js','.css','.vue','.less'],
plugin的使用
plugin是什么?
• plugin是插件的意思,通常是用于对某个现有的架构进行扩展。
• webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等。
loader和plugin区别
• loader主要用于转换某些类型的模块,它是一个转换器。
• plugin是插件,它是对webpack本身的扩展,是一个扩展器。
plugin的使用过程:
• 步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
• 步骤二:在webpack.config.js中的plugins中配置插件。
- 添加版权的Plugin
第一:修改webpack.config.js的文件,顶部添加const webpack = require(‘webpack’)
第二:与module平级
plugins: [
new webpack.BannerPlugin('最终版权归tu所有')
]
- 打包html的plugin
在真实发布项目时,发布的是dist文件夹中的内容,但是dist文件夹中如果没有index.html文件,那么打包的js等文件也就没有意义了。所以我们需要将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件
HtmlWebpackPlugin插件可以为我们做这些事情:
• 自动生成一个index.html文件(可以指定模板来生成)
• 将打包的js文件,自动通过script标签插入到body中
①安装HtmlWebpackPlugin插件
npm install html-webpack-plugin@3.2.0 --save--dev
②修改webpack.config.js的文件,顶部添加const HtmlWebpackPlugin = require('html-webpack-plugin')
③配置:与module平级
plugins: [
new webpack.BannerPlugin('最终版权归tu所有'),
new HtmlWebpackPlugin({
template: 'index.html'
})
]
④output里面的publicPath: ‘dist/’ 注释不要了
⑤删除jindex.html里面的script
- js压缩的Plugin
①安装HtmlWebpackPlugin插件
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
②修改webpack.config.js的文件,顶部添加const HtmlWebpackPlugin = require('html-webpack-plugin')
③配置:与module平级
plugins: [
new webpack.BannerPlugin('最终版权归tu所有'),
new HtmlWebpackPlugin({
template: 'index.html'
}),
new uglifyJsPlugin()
]
本地服务器
①安装webpack-dev-server
npm install --save-dev webpack-dev-server@2.9.3
②添加配置:与module平级
devServer: {
contentBase: './dist', //为哪一个文件夹提供本地服务,默认是根文件夹
inline: true //页面实时刷新
}
③在package.json中配置另外一个scripts(“build”: "webpack"下面一行添加)
"dev": "webpack-dev-server --open"
–open参数表示直接打开浏览器
④命令npm run dev