认识webpack
- webpack是一个js模块打包工具,作用:
- 1.我们只需要将webpack进行模块化开发,然后通过webpack来处理模块间的依赖关系,不仅仅是js文件,我们的css,图片,json文件等等在webpack中都可以当成模块来开发
- 2.除了打包文件,webpack还可以对资源进行处理,比如:压缩图片,将scss转换成css,将ES6语法转换成ES5,将TypeScript转换成JavaScript
和grunt/gulpd的对比
- grunt/gulp更加强调的是前端流程的自动化,模块化不是他的核心
- webpack更加强调的是模块化开发管理,而文件压缩合并,预处理等功能,是他附带的功能
- 如果功能模块依赖简单,只需要简单的合并,压缩,就使用grunt/gulp即可,如果项目使用了模块化管理,而且相互依赖强,就使用webpack
webpack的安装
- 首先,webpack依托于node环境
npm install @webpack3.6.0 -g
(全局安装)- cd到对应目录
npm install @webpack3.6.0 --save-dev
(局部安装) - 在终端直接执行webpack命令,使用的全局安装的webpack
- 在package.json中定义了script时,其中包含了webpack命令,那么使用的是局部webpack
准备工作
- 我们创建两个文件夹,dist文件夹:用于存放打包之后的文件,src文件夹:用于存放我们写的源文件
- package.json文件:通过npm init生成的
- 打包:
webpack src/main.js dist/bundle.js
- bundle.js帮我们直接处理好各种依赖,直接引入index.html文件即可:
<script src='./dist/bundle.js'></script>
webpack的配置
- 入口和出口
- 每次使用webpack的命令都需要写上入口和出口作为参数,就非常麻烦,我们可以将这两个参数写道配置当中,在运行时,直接读取
-
创建一个webpack.config.js文件 const path =require('path'); module.export = { //入口:可以是字符串/数组/对象,这里我们入口只有一个,所以写一个字符串即可 entry:'./src/main.js' //出口:通常是一个对象,里面至少包含两个重要属性,path和filename output:{ path:path.resolve(__dirname,'dist')//注意:path通常是一个绝对路径 filename:'bundle.js' } }
- package.json中自定义启动
- 我们可以在package.json的script中定义自己的执行脚本
- script会按一定的顺序寻找命令对应的位置
- 首先,会寻找本地的node_modules/.bin路径中对应的命令
- 如果没有找到,会去全局的环境变量中找
-
"script":{ "build":"webpack" } //如何执行build命令 npm run build
css-loader的使用
- 什么是loader
- 在开发中,webpack主要用于处理我们写的js代码,和js之间的依赖,但是其它es6到es5,less到css,vue文件转成js文件等功能webpack本身做不了,就需要给webpack扩展对应的loder就可以
- loader使用过程:
- 通过npm安装需要的loader
- 在webpack.config.js中的modules关键字下进行配置
- 大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法
- css文件处理
- 在src目录下css文件夹中创建一个css文件
- 在入口函数中引入(require('./css/xxx.css'))
- 单纯这样引入还没有用,需要用npm安装对应的loader(参照webpack官网),然后在webpack.config.js中的module下的rules中配置好
- 打包css需要两个loader(css-loader,style-loader),css-loader对应加载css文件,style-loader处理样式嵌入到文档中
npm install style-loader --save-dev
--save-dev表示开发时依赖,只在开发时依赖他,如果是下载vue的时候就不需要,因为vue在运行的时候也需要-
const path = require('path') module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath:"dist/" //加上这个属性,只要涉及url的东西,都会自动在前面拼接上dist/ }, module:{ rules:[ test: /.css$/, // 使用多个loader时, 是从右向左 use: [ 'style-loader', 'css-loader' ] ] } }
less文件处理
- 创建less文件,放到css文件夹中
- 在主函数中,用require引入less文件 :require('./css/xxx.less')
- 在官网中找到less-loader的说明,npm安装
npm install less-loader less --save-dev
我们不仅安装了loader还安装了less,因为webpack使用less对less文件进行编译
-
最后在webpack.config.js中的rules内添加对象选项,用于处理less文件 { 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 }] }
图片的处理
- 图片的处理我们用url-loader来处理
- 安装url-loader,配置webpack.config.js文件
-
{ loader: 'url-loader', options: { // 当加载的图片,小于limit(8kb)时,会将图片编译成base64字符串形式 // 当加载的图片,大于limit时,需要使用安装file-loader模块进行加载 limit: 8192, name:'img/[name].[hash:8].[ext]' }, }
- 当使用图片大小大于limit的时候,再次打包会发现dist文件夹下多出来了一个文件,打包后的图片
-
为了处理打包后的图片,我们在options中添加如下选项 1.img:文件要打包到的文件夹 2.name:获取图片原来的名字,放在该位置 3.hash:8 :为了防止图片名称冲突,依然使用hash,但是我们保留8位 4.ext:使用原来的拓展名 5.eg:`name:'img/[name].[hash:8].[ext]'`
- 再次打包后,我们发现图片仍然没有显示出来,是因为图片使用的路劲不正确
- 默认情况下,webpack会将生成的路径直接返回给使用者
- 但是,我们整个程序是打包在dist文件夹下的,所以我们需要在路劲下再添加一个dist/ , 在入口配置下添加publicPath:'dist/'
-
output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath:"dist/" //加上这个属性,只要涉及url的东西,都会自动在前面拼接上dist/ },
webpack配置vue
- 在开发项目中引入vue ,因为是在实际项目中也会使用vue,所有不是开发时依赖,不需要-dev,
npm install vue --save
- 修改配置之后,打包过程没有报错但是浏览器报错
- 这个错误说的是我们使用的是runtime-only版本的vue (后续有runtime-only和runtime-compiler的区别)
-
解决错误,在webpack中修改配置: resolve:{ alias:{ 'vue$':'vue/dist/vue.esm.js' } }
- 组件化开发引入:
- 在
el:'#app'
下定义tamplate属性,在el中定义tamplate,tamplate模板内容会顶替掉挂载的el模板 - 但是书写tamplate仍然非常麻烦,所以需要我们在将其抽离,再分成template,script,style三个结构
- 引入新的组件化书写方式
-
<template> <div> <h3>我是cpn组件</h3> <h3>{{ name }}</h3> </div> </template> <script > export default { name: "Cpn", data() { return { name:'conaaa' } }, } </script> <style scoped> </style>
- 安装加载器用来处理编译这个格式的组件
npm install vue-loader vue-template-compiler --save-dev
-
修改webpack.config.js文件 { test:/.vue$/, use:['vue-loader'] }
- vue-loader在13版本以后使用,还必须配置一个插件,如果不想使用插件,就要将vue-loader换成13或者在更早的版本
plugin(插件)插件的使用
- plugin和loader的区别
- loader是用于转换某些类型的模块,他是一个转换器
- plugin是插件,是对webpack本身的扩展(打包优化,文件压缩),是一个转换器
- 使用过程:
- 步骤一:通过npm安装需要的plugin
- 步骤二:在webpack.config.js中配置插件(使用插件时必要要先require引入,如:
const HtmlWebpackPlugin=require('html-webpack-plugin')
)
打包html的plugin
- 目前,index.html只存在于开发环境中,但是真实发布项目的时候,发布的是dist文件夹,我们需要使用HtmlWebpackPlugin插件将index.html引入到dist文件夹中
- 这个插件会为我们:
- 自动生成一个index.html文件(可以指定模板)
- 将打包的js文件,自动引入到script标签当中
- 安装HtmlWebpackPlugin插件
npm install html-webpack-plugin --save-dev
-
配置时我们应该先删除之前在output中添加的publicPath属性,否则插入的script标签中的src会出错 plugins:[ new HtmlWebpackPlugin({ template:'index.html' }), ]
js压缩的plugin
- 我们学习时,使用uglifyjs-webpack-plugin插件,版本号指定1.1.1,和Cli2保持一致
- 引入之后,再在plugins中配置使用
new uglifyjsWebpackPlugin()
搭建本地服务器
- webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新
- 他是一个单独的模块,在webpack中使用需要先安装他
npm install --save-dev webpack-dev-server@2.9.1
- devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:
- contentBase:为哪一个文件夹提供本地服务,默认时根文件夹(./dist)
- port:端口号
- inline:页面实时刷新
- historyApFallback:在SPA页面中,依赖HTML5的history模式
-
在webpack.config.js中的文件配置 devServer:{ contentBase:'./dist', inline:true, }
-
在package.json文件中设置npm命令 "scripts": { "dev":"webpack-dev-server --open" } --open:直接打开浏览器(可以不加)
webpack配置的分离
- 为什么要将webpack配置分离?
- 当我们生产和开发的配置需要的往往都是不一样的,通常配置会放在一起
- 比如我们想在预览编译的时候并不将js文件压缩,这样方便我们进行调试,而在生产的时候,也不需要预览配置
- 我们可以将配置文件分成三份,一份提取公共的配置文件(base.config.js),一份开发所需配置(dev.confog.js),一份生产所需配置(pod.config.js),然后在编译时用webpack工具模块(npm install webpack-merge --save-dev)将配置两两组合,就实现了webpack配置分离
-
举例: const uglifyjsWebpackPlugin=require('uglifyjs-webpack-plugin') const webpackMerge=require('webpack-merge') const baseconfig=require('./base.config') module.exports = webpackMerge(baseconfig,{ plugins:[ new uglifyjsWebpackPlugin() ], })
- 分离时需注意的几个点
- 在package.json中设置script脚本命令的时候需要注意,已经没有webpack.config.js文件了,webpack实现不了自动寻找,我们需要自行配置
-
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "webpack --config ./build/prod.config.js", "dev": "webpack-dev-server --config ./build/dev.config.js" }
- 在原来的配置中,用绝对路劲设置了编译的路劲,随着配置文件的路劲更改,编译的路劲也应该修改(在base.config.js配置文件中的出口(output)中修改)