webpack
webpack
1. 模块化
案例:
项目结构:
info.js
/**
* info.js 是用于演示各种数据信息的js文件
*/
//使用ES6语法规范导出数据
export const name = '张三';
export const age = 18;
export const height = 18.88;
mathUtils.js
/**
* mathUtils.js 是提供各种数学计算方法的js文件
*
*/
/**
* 计算两个数的和
* @param num1 加数1
* @param num2 加数2
* @returns {*} 和
*/
function add(num1,num2){
return num1 + num2;
}
/**
* 计算两个数的乘积
* @param num1 积数
* @param num2 积数
* @returns {number} 乘积
*/
function mul(num1,num2){
return num1 * num2;
}
/**
* 使用commonJs 方式导出
* @type {{add: (function(*, *): *), mul: (function(*, *): number)}}
*/
// module.exports = {
// add,mul
// }
/**
* 使用 ES6规范导出
*/
export {add,mul};
main.js
/**
* main.js是用来配置导出的js文件,所有的js导出的工作,都是通过main.js来完成的
*/
//1. 使用commonJs的模块化规范 导入
//const {add,mul} = require('./mathUtils.js');
//1. 使用ES6的模块化规范 导入
import {add,mul} from './mathUtils.js';
//使用导入的方法
let he = add(20,30);
console.log('求和方法:',he);
let ji = mul(20,30);
console.log('求乘积方法:',ji);
//2. 使用ES6的模块化的规范 导入
import{name,age,height} from './info.js';
//使用导入的数据
console.log(name);
console.log(age);
console.log(height);
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01-webpack的起步</title>
</head>
<body>
<!--使用模块化的方式引用js文件-->
<script src="./src/main.js" type="module"></script>
</body>
</html>
在浏览器运行index.html 结果:
2. webPack的理解
从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具。
前端模块化的一些方案: AMD、CMD、CommonJS、ES6。 其中 ES6的规范,浏览器是直接支持的,而其他的规范,我们需要利用打包工具,进行转换之后,才能被浏览器所认识.
常用的打包工具:
grunt/gulp, webpack
-
在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。
-
并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。
-
而webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
-
而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用(在后续我们会看到)。
-
这就是webpack中模块化的概念。
如何理解打包:
-
理解了webpack可以帮助我们进行模块化,并且处理模块间的各种复杂关系后,打包的概念就非常好理解了。
-
就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
-
并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成 JavaScript等等操作。
-
但是打包的操作似乎grunt/gulp也可以帮助我们完成,它们有什么不同呢?
3. webpack的安装
-
安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm
- NodeJs下载地址:
https://nodejs.org/en/download/
- 查看node版本:
node -v
- NodeJs下载地址:
-
全局安装webpack(这里我先指定版本号3.6.0,因为vue cli2依赖该版本)
- 命令
npm install webpack@3.6.0 -g
- 命令
-
局部安装webpack(后续才需要)
- 命令
npm install webpack@3.6.0 --save-dev
- 命令
-
为什么全局安装后,还需要局部安装呢?
- 在终端直接执行webpack命令,使用的全局安装的webpack
- 当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack
4. 使用webpack进行打包
dist → distribution 发布
webpack 支持上述所有的模块化(ES6,common.js,....)的方式,它会在打包时,将这些模块化的打包方式,自动转换成浏览器可识别的js的代码.
工程结构:
webpack打包命令: webpack src/main.js dist/bundle.js
即:将指定文件夹下的文件,打包到另一个指定文件夹下,并为其指定名称.
上述命令执行完成之后,会在 dist 文件夹下生成bundle.js
的文件,我们在 index.html
文件中,引用这个文件即可.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01-webpack的起步</title>
</head>
<body>
<!--使用模块化的方式引用js文件-->
<script src="./dist/bundle.js"></script>
</body>
</html>
运行index.html
执行结果如下:
我们发现如果我们总是写 webpack src/main.js dist/bundle.js
这样的命令来,执行打包,操作很费劲,实际上,我们可以通过 配置的方式,来实现打包操作.
5. webpack的配置
我们需要在工程下创建一个名为webpack.config.js
的文件,这个文件就是用来配置webpack的行为的文件.
5-1. 打包配置
//通过commonjs的方式来导入node中path包的功能
const path = require('path');
// 通过commonjs的方式来导出配置
module.exports = {
entry:'./src/main.js', //打包入口
output:{ //打包出口
path: path.resolve(__dirname,'dist'), //路径 (注意: path需要绝对路径)
filename:'bundle.js' //文件名
}
}
path.resolve();
方法的作用是拼接路径. 可以理解成是C#
中的Path.Combo()
方法, __dirname
可以获取当前文件所在的绝对路径.
上面的代码中,我们需要引用nodeJs中的path包,那么我们就需要注意,一旦项目中需要使用到node相关的东西,那么我们就需要,在项目的路径下对node进行初始化. 初始化命令: npm init
在初始化命令执行结束之后,在工程下会出现一个名为 package.json
的配置文件,内容如下:
package.json
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
我们可以在package.json
文件中保存的是,对webpack,依赖文件的相关配置.
如果当前项目已经是一个完成的了的工程,但是本地没有依赖文件,那么我们可以在当前工程的目录下,执行npm install
,来安装此工程所需要的依赖文件.
以上工作完成之后,我们就可以直接使用webpack
命令来进行打包操作了.
在已经使用npm管理的项目中,我们可以使用 npm run build
命令,来和webpack
命令,建立对应关系,以此来使用npm run build
来进行打包工作,那么我们应该如何配置呢? 我们需要在package.json
文件中,对这个操作进行配置.
package.json
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"author": "",
"license": "ISC"
}
我们在package.json
的scripts
配置节中,添加 "build":"webpack"
的配置,就能使用 npm run build
命令来映射执行webpack
命令的打包操作.
在package.json
中配置的好处是,如果项目本地安装了依赖,那么使用npm
命令时,优先使用的是本地配置依赖, 而如果直接在终端中使用webpack命令的话,使用的就是全局的依赖了,
- package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。
- 首先,会寻找本地的node_modules/.bin路径中对应的命令。
- 如果没有找到,会去全局的环境变量中寻找。
为什么说是有好处呢?
因为比如package.json
中,项目配置需要依赖项目需要webpack
版本是4.1.1才能进行打包,而全局的webpack
版本只有3.0.0
,那么在打包的时候,就会出错,所以优先使用本地配置,是很重要的.
在本地安装webpack
的方法,就是在项目路径下执行命令npm install webpack@3.6.0 --save-dev
安装即可,这种在项目下安装依赖的行为,我们称之为开发时依赖. 向对应的在发布后,我们也需要运行时依赖.
在命令执行完成之后,我们可以在package.json
文件中发现多了如下配置:
我们会发现webpack
的配置,被放入到了devDependencies
配置节下,表明此时的依赖,属于开发时依赖.
而运行时依赖,的配置会被配置到dependencies
中.
安装完webpack
包之后,我们会发现我们的工程下多了一个名为node_modules
的文件夹,我们所有的本地依赖,都会被放置在node_modules
文件夹中.
6. 什么是loader
- loader是webpack中一个非常核心的概念。
- webpack用来做什么呢?
- 在我们之前的实例中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖。
- 但是,在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等。
- 对于webpack本身的能力来说,对于这些转化是不支持的。
- 那怎么办呢?给webpack扩展对应的loader就可以啦。
- loader使用过程:
- 步骤一:通过npm安装需要使用的loader
- 步骤二:在webpack.config.js中的modules关键字下进行配置
- 大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法。
- 中文网地址
https://www.webpackjs.com/loaders/
- 中文网地址
6-1. loader css文件
最终工程结构:
工程结构图
我们在工程下创建以下css文件,最终的目的是,我们也需要将它通过webpack打包, 即把css文件当成一个模块,也和其他js文件一样打包到 bundle.js
中
normal.css
body{
background-color: pink;
}
所以我们需要先在main.js
中,导入此css文件
此处如果我们打包就会遇到以下问题:
上面的图片中,描述了为什么我们打包css文件出错了,它是说,我们对css文件进行打包时,没有合适的打包依赖,,解决步骤:
- 根据webpack官网提供的css样式依赖,进行安装.(安装完成之后,会在
package.json
文件中出现相应的依赖配置信息) - 在webpack.config.js文件中,对依赖,如何使用进行配置.webpack官网也会配置配置的例子.
- 再运行
npm run build
命令进行打包.
此处我们安装css依来loader命令 npm install --save-dev css-loader@2.0.2
在webpack.config.js中进行配置如下:
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
此时我们还需要添加一个loader依赖, 因为css-loader
只负责加载css样式,并不负责css样式的解析,如果我们想要让css样式生效,那么我们还需要再安装一个依赖.
此处我们安装css解析依来loader命令 npm install style-loader@0.23.1 --save-dev
在webpack.config.js中进行配置如下:
module: {
rules: [
{
test: /\.css$/,
use: [
// css-loader只负责将css文件进行加载
// style-loader负责将样式添加到DOM中
// 使用多个loader时, 是从右向左
{ loader: "style-loader" },
{ loader: "css-loader" }
]
}
]
}
再使用 npm run build
命令打包即可.
6-2. 安装less依赖
命令npm install --save-dev less-loader@4.1.0 less@3.9.0
配置:
{
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
}]
}
6-3. 安装图片资源的依赖
命令npm install --save-dev url-loader@1.1.2
webpack.config.js
中的配置如下:
{
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
//当文件大小,小于limit的值时,会将图片编译成base64字符串形式
//当文件大小,大于limit的值时,则需要使用`file-loader`依赖
limit: 13000,
name: 'img/[name].[hash:8].[ext]' //指定文件名称格式
}
}
]
}
file-loader 依赖安装命令
命令: npm install --save-dev file-loader@3.0.1
此时,我们在打包,之后运行发现没有报错,但是浏览器也不显示背景图,即,如果我们通过的是file-loader
依赖,来加载的图片,我们就需要将这个被依赖的图片资源进行打包.
但是,我们在开发中依赖的图片文件在src中,但是发布之后的图片依赖,应该是在dist中,所以我们需要在这个地方进行干预一下,我们需要在webpack.config.js
配置文件的output
节点中添加一个配置publicPath:"dist/"
,加了这个配置之后,以后凡是涉及到url的部分,都会在链接前面加上dist/
,前缀.