- 安装webpack
- webpack核心概念:入口、输出、加载器、插件、模块、模式
一、安装webpack
1.安装webpack之前需要安装nodejs环境,在使用nodejs环境自带的包管理工具npm进行下载,由于网络环境问题,建议安装先安装淘宝的镜像cnpm来实现下载。
npm install webpack -g
由于webpack从3版本升级到4版本,拆分了命令行接口webpack-cli,所以这时候你直接使用webpack会报错,还需要下载安装一个webpack-cli,再使用webpack。
npm install webpack-cli -g
然后就可以开始再你的工作区间使用webpack了,需要注意的是在你的工具区间内必须要有src文件夹,并且在文件下面有个index.js文件,这是针对无配置的测试情况,有配置的大神跳过。
webpack
通过webpack打包后会在工具区间下生成一个文件夹dist,并且文件夹下有一个main.js,这个main.js是由webpack打包生成的,在HTML结构文件中引入这个main.js测试你的代码。
2.在webpack中默认支持ES6模块化和Commonjs模块化,并且可以同时混合使用。看下面示例:(同时演示通过webpack指定打包文件且指定打包到某个文件)
使用ES6的模块化定义一个sum.js
export default function sum(a,b){ return a + b; }
使用Commonjs模块化定义一个minus.js
module.exports = function(a,b){ return a - b; }
在demo.js主入口文件引入这两个模块,并使用模块的功能:
import sum from './sum'; var minus = require('./minus'); console.log(sum(2,4),minus(4,2));
然后通过webpack将demo.js打包到bundle.js文件中:
webpack demo.js -o bundle.js
再在demo.html结构文件中引入打包后的bundle.js文件。
<script src="./bundle.js"></script>
打开demo.html文件,查看控制台,操作成功的话会打印出:6 2
3.为了更方便管理项目,除了在全局安装webpack以外有必要在当前项目的工作区间上安装一个局部的webpack,一是可能全局的webpack的版本可能与全局的版本不同,而是可以更好的管理插件。
//下载安装局部的webpack----(--save-dev可以简写成-D) cnpm install webpack --save-dev
下载安装完成以后在工作区间下可以看到生成了一个node_modules文件夹,还有生成一个package.json文件。node_nodules文件夹里面是webpack依赖的包,package.json则是记录当前工作区间都安装了哪些包,第一次安装在这个文件里只记录了webpack的信息,如:
{ "devDependencies": { "webpack": "^4.35.0" } }
比如再在当前工作区间上安装一个jquery:
cnpm install jquery -D
package.json的记录多出了一个jquery的信息,实际jquery包被存到了node_modules文件夹下:
{ "devDependencies": { "jquery": "^3.4.1", "webpack": "^4.35.0" } }
这个package.json文件有什么作用呢?除了可以查看项目依赖的包以外,还有当你要迁移你的工作区间或者向同事拷贝一个正在进行开发维护的项目时,并不需要将node_modules的包拷贝给他,只需要将这个package.json文件拷贝一份即可,拿到这个package.json后在新的工作区间上执行以下指令,就可以将package.json文件中记录的所有依赖包前部下载到当前工作区间上:
npm install
二、webpack核心概念
- 入口(entry)
- 输出(output)
- 加载器(loader)
- 插件(plugins)
- 模式(mode)
- 模块
首先,在工作区间创建一个后缀为.config.js的配置文件,这个配置文件用来配置入口、输出、加载器、插件、模块、模式。意思就是由这个配置文件告诉webpack从那个文件开始打包操作,打包到那个文件,非JS文件如何编译转码等操作,当打包JS文件时遇到需要依赖的模块时根据配置的模块信息进行打包操作,是按照开发模式还是按照生产模式打包。这个配置文件都将为你自动完成这些操作。注意.config.js配置文件遵循Commonjs规范。
2.1.1在config.js配置文件中配置单入口文件:在配置模块中定义entry属性,然后将入口文件路径以字符串的方式传入,注意这里需要文件后缀。
module.exports = { entry:'./src/index.js' }
2.1.2在config.js配置文件中配置多个入口文件:entry属性这时候就要写成对象值了,然后给每个入口文件定义一个名称作为该对象的属性名,然后将对应的入口文件路径作为属性值给该属性。
1 module.exports = { 2 entry:{ 3 index:'./src/index.js', 4 app:'./src/app.js' 5 } 6 }
2.2.1在config.js配置输出文件信息:在配置模块中定义output属性,并给这个属性赋值一个对象,对象中有两个属性分别是path和filename,path用来设置文件输出路径,filename用来设置文件名。
var path = require('path'); module.exports = { output:{ path:path.resolve(__dirname,'dist'), filename:'bundle.js' } }
注意path属性的配置,path.resolve(__dirname,'dist')的意思就是在path这个变量上找到当前路径下的‘dist’文件夹,如果当前文件夹下没有‘dist’文件夹就会自动创建‘dist’文件夹。path本身是一个node环境模块,所以需要引入这个模块,然后在调用path的resolve()方法获取当前模块下指定的文件夹,这个方法会返回该文件夹的绝对路径。交给webpack用来操作输出文件。
所以,这个输出的意思就是将打包好的文件存储到当前工作环境下的dist文件夹下,并设置这个打包好的文件名称为bundle.js。
2.2.2有了入口文件的的配置模式,必然输出也就需要针对这种多入口文件对应的输出多个打包文件,所以文件名肯定不能像上面一样写死,看示例怎么解决的:
1 var path = require('path'); 2 module.exports = { 3 output:{ 4 path:path.resolve(__dirname,'dist'), 5 filename:'[name].bundle.js' 6 } 7 }
在固定的文件名称前面加上一个块[name],设置为动态命名,这个那么就是入口文件路径对应属性名的名称。
我们知道,less是不能直接作用在HTML文件上的,在webpack打包过程中可以直接通过加载器将less转换成css文件,甚至直接转换编译成行间样式,这时候就需要用到加载器。当然加载器不只是为了实现less的转换,还能处理各种不能直接被浏览器使用的文件格式的文件,比如TypeScript。
先通过转换less文件来了解加载器:
1 module.exports = { 2 module:{ 3 rules:[ 4 {test: /.less$/,use:['style-loader','css-loader','less-loader']} 5 ] 6 } 7 }
在配置文件中添加对象属性module,然后在module中添加对象属性rules,然后将各种需要解析的文件以及解析这个文件格式的loader以键值对的方式添加进去。文件类型用test表示,然后再以正则表达式的方式匹配文件后缀作为test的值;use则用来表示需要的加载器,加载器的值可以是一个字符串(执行单个加载器),也可以是一个数组(多个加载器迭代加载),多个加载器迭代加载的方式是从后向前进行迭代加载。
要注意的是这些加载器是需要下载的,然后还要再主入口文件中使用模块化依赖对应文件,不然webpack没办法追踪到对应的文件。
cnpm install style-loader less-loader css-loader less --save-dev
在主入口文件中依赖对应的文件:
import './src/demo.less';
关于插件这部分不太可能在这里解释清楚,可以理解为扩展webpack的功能。其实webpack自带的加载器loader也是建立在系统的plugins基础之上的,既然是外部的扩展功能那就要先引入,然后再在配置中配置。实际上却是是这样的,我们通过扩展一个html-webpack-plugin插件来示范以下,这里不具体介绍这个插件的用途,后面会有具体剖析插件的博客来解析:
var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { plugins: [ new HtmlWebpackPlugin() ] }
然后我再次执行webpack打包,如果正常的完成打包的话会在dist文件夹下出现一个index.html文件,但是我在打包环节出现了以下小错误:
Error: Cannot find module 'webpack/lib/node/NodeTemplatePlugin'
具体在这里不解释这个错误的原因了,我在控制台中执行了这行命令解决了这个错误:
npm link webpack --save-dev
用cnpm也是可以的,然后再次执行顺利打包,dist文件夹出现了index.html文件。
2.5.1模式是用来控制打包模式的,所谓打包模式通常被称为生产模式和开发模式,两者的区别就是生产模式是压缩版本代码,不方便测试,因为如果使用压缩代码测试的话,如果出现异常情况报错都是在第一行,不方便debug。在webpack中如果没有设置模式就会默认为生产模式,打包后的代码是经过压缩的。
module.exports = { mode:'production'//生产模式 mode:'development'//开发模式 }
这个代码你别两个都复制了,我是为了展示这两个模式的设置方式把两个模式都写入了示例。在实际开发时我们一般会需要两个配置文件,一个用于开发打包,一个用于生产打包,在控制台执行打包时采用指定的配置文件打包。