1、安装完node 和 git bash以后,新建文件夹webpackDemo。进入文件夹,使用npm init去初始这个项目。完成之后可以发现该命令就是生成一个package.json文件。描述了我们这个node项目的一些信息:
我们也可以去增加一些内容,比如:
private: true的意思就是我们的这个项目是一个私有的项目,不会被发布到npm的线上仓库里。
去掉"main": "index.js":因为我们的这个项目不会被外部引用,只是自己来用,没有必要向外暴露一个js文件。
2、安装Webpack有两种方式,先介绍第一种安装方式。
A. 全局安装
安装命令: npm install webpack webpack-cli -g
此时我们的webpack和webpack-cli已经安装成功了。
注意:我们不推荐通过全局的方式来安装webpack。比如说我有两个项目,假设webpack的版本号是固定的,都是4.26.0。但是我们一个项目是根据webpack3配置的,另一个项目是通过webpack4配置的,由于全局安装的webpack版本是4.26.0,根据webpack3配置的那个项目是运行不起来的。此时解决办法比较麻烦,需要删除当前的webpack4,重新安装webpakc3才能运行当前的项目。但是假设这两个项目之间有依赖,需要启动两个项目,此时全局的安装方式肯定是不能启动的。所以推荐在项目内安装Webpack。
B. 项目内安装
首先需要卸载我们之前全局安装的webpack。
卸载命令: npm uninstall webpack webpack-cli -g
卸载完成之后就可以在项目中安装webpack了,
安装命令: npm install webpack webpack-cli --save-dev 或者 npm install webpack webpack-cli -D
安装成功之后,可以发现项目中增加了node_modules文件夹,这里面保存的是webpack以及它所依赖的一些第三方的包。我们此时输入webpack -v发现找不到它的版本,这是因为node首先会去全局中找webpack,但是我们不是在全局安装的webpack。但是node提供了一个npx命令帮助我们去运行,输入:npx webpack -v,此时能够显示出版本号。这是因为npx会帮助我们去本项目中的node_modules文件夹里找webpack。
1、之前开发网页:
index.html
Document
这是我们的网页内容
index.js
var dom = document.getElementById('root');
var header = document.createElement('div');
header.innerText = 'header';
dom.append(header);
var sidebar = document.createElement('div');
sidebar.innerText = 'sidebar';
dom.append(sidebar);
var content = document.createElement('div');
content.innerText = 'content';
dom.append(content);
效果:
上面这种面向过程的写法已经不能满足目前开发者的需求了,如果js的逻辑越来越多,全部放在一个文件中的这种面向过程的写法后期维护起来很麻烦。所以开始使用面向对象的编程方式来开发,上面页面中有三个部分,那我们就用三个对象来写逻辑部分:
index.html
Document
这是我们的网页内容
header.js
function Header() {
var header = document.createElement('div');
header.innerText = 'header';
dom.append(header);
}
sidebar.js
function Sidebar() {
var sidebar = document.createElement('div');
sidebar.innerText = 'sidebar';
dom.append(sidebar);
}
content.js
function Content() {
var content = document.createElement('div');
content.innerText = 'content';
dom.append(content);
}
index.js
var dom = document.getElementById('root');
new Header();
new Sidebar();
new Content();
效果一样,这样的话我们就通过面向对象改造了我们的代码,使用面向对象可以使我们的代码更具有维护性,因为不同部分的逻辑都放在各自不同部分的对象里,这样代码维护起来很方便,哪部分出错了就去那部分修改即可,这就是面向对象的优势。但是上面的写法也有一定的问题:
(1)一个html文件引用了多个js文件,导致整个页面的加载速度会变慢,因为多出了三个http请求。
(2)我们不能很直观的从index.js文件中看出不同对象所对应的文件在哪里,要想知道,我们就必须去html文件中查看。
(3)我们不能很方便的去查错。假如我们把content.js文件放在index.js后面引用,控制报错显示是index.js中有错误。
为了解决上述问题,我们可以使用webpack:
文件代码进行了一点修改:
index.html
Document
这是我们的网页内容
index.js
//ES Module 模块引入方式
import Header from './header.js';
import Sidebar from './sidebar.js';
import Content from './content.js';
var dom = document.getElementById('root');
new Header();
new Sidebar();
new Content();
效果:
此时文件夹就多了一个dist文件夹,里面有一个main.js文件。但是这是页面还是报错,想要实现效果,我们需要对代码进行一点修改:
index.html
Document
这是我们的网页内容
header.js, 另外两个模块文件也做类似的修改即可
function Header() {
var dom = document.getElementById('root');
var header = document.createElement('div');
header.innerText = 'header';
dom.append(header);
}
export default Header;
index.js
//ES Module 模块引入方式
import Header from './header.js';
import Sidebar from './sidebar.js';
import Content from './content.js';
new Header();
new Sidebar();
new Content();
此时重新运行一遍npx webpack index.js即可正常显示出效果了。
webpack的核心定义是模块打包工具
除了上面使用的ES Module 模块引入方式以外,还有CommonJS(node里面最常用的一个模块引入规范)、CMD、AMD。webpack对以上的模块引入方式都能够正常识别。
CommonJS模块引入方式实现上面的效果:
header.js, 另外两个模块文件也做类似的修改即可
function Header() {
var dom = document.getElementById('root');
var header = document.createElement('div');
header.innerText = 'header';
dom.append(header);
}
module.exports = Header;
index.js
//ES Module 模块引入方式
// import Header from './header.js';
// import Sidebar from './sidebar.js';
// import Content from './content.js';
//CommonJS模块引入方式
var Header = require('./header.js');
var Sidebar = require('./sidebar.js');
var Content = require('./content.js');
new Header();
new Sidebar();
new Content();
重新运行npx webpack index.js之后效果一样。
webpack发展到现在,它不光能打包js文件,还能打包css文件,甚至是png等的图片文件。
1、假如在项目中,我们想编写配置webpack的文件,可以这么做:
const path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
//__dirname指的是webpack.config.js当前所在的目录路径,第二个参数是文件夹的名字
path: path.resolve(__dirname, 'bundle')
}
}
entry: 我们这个项目要做打包的话,从哪一个项目开始打包。
output: 打包文件放置位置。这是一个对象,内部配置属性: filename:打包后文件的名字;path:打包出的文件要放在哪一个文件夹下,必须填绝对路径,而且使用前需要引入一个node的核心模块-path;
运行npx webpack,可以发现目录中多了bundle文件夹,里面有一个bundle.js文件。
此时webpack的工作流程如下:
我们运行npx webpack的时候,一开始webpack并不知道自己该如何去打包,于是它就会去找默认的配置文件,找到webpack.config.js这个文件,然后就知道了如何去打包,如何去输出。从而帮助我们去完成打包的流程。
假设我们打包配置文件不是默认名字,而是webpackconfig.js,此时执行npx webpack就会报错,因为webpack找不到默认的配置文件。解决办法:
使用这个打包命令: npx webpack --config webpackconfig.js,意思就是以webpackconfig.js为配置文件来进行打包。此时便成功打包了。
2、结合上面学习的知识点,我们对lessons这个项目进行优化。
项目中的index.js不能由浏览器直接运行,它需要webpack打包,打包后最终的代码才能在浏览器中运行。所以index.js并不是我们放在浏览器中直接运行的代码,它是我们的源代码,一般我们都是把源代码放在一个src的目录里。header.js、sidebar.js、content.js都是源代码,我们将它们都放在src文件夹里面。
目录结构:
此时我们就需要把src目录下的index.js打包成可以执行的js,那么我们就需要把配置文件做一些修改了。
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
//__dirname指的是webpack.config.js当前所在的目录路径,第二个参数是文件夹的名字
path: path.resolve(__dirname, 'dist')
}
}
此时执行npx webpack就打包成功了。问题:之前vue项目,我们都是使用npm run命令来执行一些操作的,此处确实使用npx,我们想继续使用npm run来执行,可以在scripts这么配置:
package.json文件中:
"scripts": {
"bundle": "webpack"
}
意思就是当你执行bundle这个命令,它就会自动帮你执行webpack这个命令。首先会去项目中找是否有Webpack,没有的话才会去全局找
此时输入npm run bundle就自动会帮我们进行打包了。
我们将index.html放进dist文件夹下,修改引用文件的路径之后发现此时的项目目录与之前接触的react或vue项目目录很相似了。
到目前为止,我们介绍了三种运行Webpack的方式:
我们之前安装的webpack-cli的作用就是帮助我们在命令行中正确执行webpack的指令,假设我们没有安装它,那么我们就没法在命令行里运行webpack或npx webpack这样的指令。
注意:我们不写webpack的配置文件也能打包,只不过它使用的是webpack的默认配置。但是在做工程打包的时候,每个工程它的特点和复杂度都不同,一般来说我们都需要根据工程要求自己来配置复杂的Webpack配置文件。
执行npm run bundle打包之后,输出的这些命令的意思如下:
entry: './src/index.js'
是下面的简写方式
entry: {
main: './src/index.js'
}
const path = require('path');
module.exports = {
mode: 'production', //意思是打包后的文件被压缩,我们不配置mode的话默认值是被压缩,但是会警告。
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
mode的另一个值是development,意思就是打包后的文件不被压缩。