全局安装webpack
npm install -g webpack
进入项目目录,生成package.json文件
npm init//对应的package.json文件
{"name": "test","version": "1.0.0","description": "package.json test","main": "webpack.config.js","dependencies": {"webpack": "^4.46.0"},"devDependencies": {},"scripts": {"build": "webpack" //加上这一句,当我们执行npm run build时它会去我们局部的webpack中去寻找命令,如果找不到再去全局寻找},"author": "jianghuxiuxing","license": "ISC"
}
安装webpack依赖
npm install webpack --save-dev
新建index.html
// 在页面中引入test.js
新建入口文件main.js
alert('hello world')
编译main.js并打包到test.js
webpack main.js test.js// 此时会自动生成test.js文件
// 运行index.html将弹出:hello world
新建模块module.js,并修改main.js
// module.js
module.exports = 'It is module.js!'// main.js
alert('hello world');
alert(require('./module.js')) // 再次编译打包,后刷新页面
// 其它模块可同样类似引入
loader是webpack中一个非常核心的概念,前面提到loader是主要用来做文件转化的。虽然js代码我们可以用webpack处理并且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的官网中找到,并且学习对应的用法。
引入css loader
npm install css-loader style-loader
去掉loader前缀
// 通过新建文件webpack.config.js
var webpack = require('webpack')
module.exports = {entry: './main.js',output: {path: __dir,filename: 'test.js'},module: {loaders: [{test: /\.css$/, loader: 'style-loader!css-loader'}]}
}
在main.js中引入style.css
require("./style.css")
引入less loader
需要安装对应的loader。注意:我们这里还安装了less,因为webpack会使用less对less文件进行编译。其次,修改对应的配置文件,添加一个rules选项,用于处理.less文件
npm install --save-dev less-loader less
{test: /\.css$/, use: [{loader:'style-loader'},{loader:'css-loader'},{loader:'less-loader'}]
}
在没有引入babel等能力的时候,webpack打包后的js文件的ES6语法并没有转成ES5,那么就意味着可能一些对ES6还不支持的浏览器没有办法很好的运行我们的代码。在webpack中,通过babel-loader的方式来接入babel的能力,babel配置文件与单独使用babel时相同。
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
在webpack中使用babel时建议开启babel的缓存能力,即cacheDiretory,统计显示,在大型项目中,构建速度可以提升近1倍,webpack的配置文件示例如下:
module: {rules: [{test: /\.[j,t]sx?$/,exclude: /node_modules/,use: {loader: 'babel-loader?cacheDirectory'}}]}
webpack main.js test.js --watch
webpack基于其强大的扩展能力,可以让开发者更轻松的定制化实现需求。如果你在社区找不到你的应用场景的解决方案,那就需要自己动手了写loader或者plugin了。
webpack loader,以comment-require-loader为例:
module.exports = function (content) {return replace(content);
};
loader的入口需要导出一个函数,这个函数要干的事情就是转换一个文件的内容。函数接收的参数content是一个文件在转换前的字符串形式内容,需要返回一个新的字符串形式内容作为转换后的结果,所有通过模块化导入的文件都会经过loader。从这里可以看出loader只能处理一个个单独的文件而不能处理代码块。
webpack plugin的两个核心概念:
Compiler 和 Compilation 都会分发一系列事件。webpack生命周期里有非常多的事件,开发者可以根据对应的事件节点定制自己的功能。
以end-webpack-plugin为例:
class EndWebpackPlugin {constructor(doneCallback, failCallback) {this.doneCallback = doneCallback;this.failCallback = failCallback;}apply(compiler) {// 监听webpack生命周期里的事件,做相应的处理compiler.plugin('done', (stats) => {this.doneCallback(stats);});compiler.plugin('failed', (err) => {this.failCallback(err);});}
}module.exports = EndWebpackPlugin;
uglifyjs-webpack-plugin:通过UglifyJS去压缩js代码;
作用不同:
用法不同:
在前端卷的无法自拔的情形下,各大脚手架或构建工具层出不穷,最近的Turbopack更是宣扬自己比webpack快700倍,虽说真实场景和数据可信度暂且不论,就形与势来说我们不能仅专注一个构建工具的使用,更不能只停留在表层不深入研究其原理。但不管是老旧项目难以更新换代脱离webpack的束缚,还是webpack本身的不断进化,我们总之是可以看到webpack的架构扩展、插件化等优秀理念的,所以我们要时刻保持着敬畏之心,毕竟技术的推陈出新也是踩在巨人的肩膀上完成的,技术没有银弹,我们需要根据自己的场景选择适用于当下及未来一段时间内的可控变化权衡后所选用的技术。微信首发构建系列之webpack窥探下,欢迎关注微信公众号