webpack 是一个打包工具,目的就是把有依赖关系的各种文件打包成一系列的静态资源
webpack有一个配置文件,核心内容:
- entry:入口文件
- output:出口 webpack处理完成后文件存放位置
- loader:模块转换器,将模块原内容转换成新内容,
- 插件:在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果
webpack配置
1.初始化项目
新建webpack-demo目录
npm init -y
安装 webpack和webpack-cli
npm install webpack webpack-cli --save-dev
新建/src/index.js
class Person{
constructor(name){
this.name = name;
}
sayName(){
console.log('my name is'+this.name);
}
}
const tom = new Person('tom');
从 wepack4 开始, webpack 在不引入任何配置文件的情况下就可以使用。
使用 npx webpack --mode=development打包,默认模式为production,使用development模式方便查看打包后的代码
执行完成项目目录下生成dist目录,里面有一个main.js文件。
webpack 有默认配置,默认的入口文件是 ./src,默认打包到dist/main.js。
dist/main.js中,src/index.js还是es6代码,没有转换es5
2.模式(mode)
mode可选参数有evelopment,production或none,用来启用 webpack 内置在相应环境下的优化。其默认值为 production。
evelopment:将process.env.NODE_ENV的值设置为development,启用NamedChunksPlugin和NamedModulesPlugin添加mode到webpack.config.jsproduction:将process.env.NODE_ENV的值设置为production,启用FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和UglifyJsPluginnone:不使用任何默认优化选项
module.exports={
//...
mode:'development',
module:{
//...
}
}
现在执行 npx webpack打包,不用传入参数了
3.loader
让webpack支持非js json的模块
-
babel-loader (处理js) 使用
babel-loader将es6转为es5 安装babel-loadernpm install babel-loader --save-dev创建
webpack.config.js配置:module.exports = { module:{ rules:[ { test:/\.jsx?$/,//匹配文件类型 use:['babel-loader'],//使用什么loader exclude:/node_modules/,//排除node_modules } ] } }然后还需要配置
babel,还需要安装依赖:npm install @babel/core @babel/preset-env @babel/ plugin-transform-runtime --save-dev npm install @babel/runtime @babel/runtime-corejs3创建.babelrc文件,配置:
{ "presets": ["@babel/preset-env"], "plugins": [ [ "@babel/plugin-transform-runtime", { "corejs": 3 } ] ] }babel的配置可以写在.babelrc中,也可以在 webpack.config.js 中进行配置。在webpack中配置 babel,
module.exports = { module: { rules: [ { test: /\.jsx?$/, use: { loader: 'babel-loader', options: { presets: ["@babel/preset-env"], plugins: [ [ "@babel/plugin-transform-runtime", { "corejs": 3 } ] ] } }, exclude: /node_modules/ } ] } } -
css-loader (处理css) 要在js中
importcss文件,要使用style-loader和css-loader- style-loader 将
css插入到html中 - css-loader 将
css文件打包到js中 安装style-loader和css-loader
npm install style-loader css-loader --save-devwebpack.config.js配置:module.exports = { module:{ rules:[ { test:/\.jsx?$/,//匹配文件类型 use:['babel-loader'],//使用什么loader exclude:/node_modules/,//排除node_modules } ] } }创建
/src/index.css文件,随便写点样式:body{ background-color:pink; }在
src/index.js中importindex.cssimport './idnex.css'执行打包 创建
index.html将mainjs引入<script src="./dist/main.js"></script>在浏览器查看html,样式生效 除了上述loader还有很多常用loader
- 样式文件处理有
less-loader、postcss-loader、sass-loader等等 - 图片/字体文件处理有
url-loader、file-loader
- style-loader 将
4.plugin
webpack的功能扩展,对输出的资源进行二次加工
上面我们手动创建index.html文件在浏览器中查看,有时我们会在打包文件中带上 hash,内容改变后生成的js文件名会不同,
-
所以要动态创建
html文件,可以使用html-webpack-plugin- 新建
public目录,在里面创建index.html npm install html-webpack-plugin -D安装插件- 在
webpack.config.js中添加配置
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode:'development', module:{ //... }, plugins:[ new HtmlWebpackPlugin({ template:'./public/index.html', filename:'index.html',//打包后的文件名 }) ] }执行打包,此时
dist目录下生成了index.html和main.js而且html文件中自动引入了js文件 - 新建
-
每次构建前先删除上一次的构建,可以使用
clean-webpack-pluginnpm install clean-webpack-plugin -D安装插件- 在
webpack.config.js中添加配置
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { entry:'./src/index.js', output:{ filename:'main.js', path:path.resolve(__dirname,'dist')//必须绝对路径 } mode:'development', module:{ //... }, plugins:[ new CleanWebpackPlugin() ] }还有很多常用的插件,参考官方文档配置
简单实现loader和plugin
- 简单实现
less-loader、css-loader、style-loader1. 创建my-loaders目录,创建文件my-less-loader.js、my-css-loader.js、my-style-loader.js; 2.my-less-loader.js中使用less的api将less语法转换成css语法,安装lessnpm install less -Dconst less = require('less'); module.exports = function(source){ less.render(source,(error,output)=>{ this.callback(error,output); }) }
3. `my-css-loader.js`将css序列化
```js
// 序列化css
module.exports = function(source){
return JSON.stringify(source);
}
```
4. `my-style-loader.js`创建`style`标签,将内容插入`style`标签,将`style`标签插入`header`
```js
module.exports = function(source){
return `
cosnt tag = document.createElement("style");
tag.innerHtml = ${source};
document.header.appendChild(tag);
`
}
```
修改webpack.config.js
```js
module.exports={
module:{
rules:[
{
test:/\.less$/,
use:['my-style-loader','my-css-loader','my-less-loader']
}
]
}
resolveLoader:{
modules: ['node_modules','./my-loaders'],//配置webpack从哪里去找依赖, 默认值node_modules
},
}
```
2. 简单实现一个plugin
plugin是一个class,有一个核心方法apply,在插件安装时会被调用,接收compiler对象作为参数,可以在apply中访问到compiler对象
接下来实现一个统计输出到dist目录文件的清单
1. 创建my-plugin,新建TxtWebpackPlugin.js文件
2. compiler对象提供了很多钩子,在emit钩子中处理
js class TxtWebpackPlugin { apply(compiler){ compiler.hooks.emit.tap('TxtWebpackPlugin',complation=>{ let res = ''; for(let key in compilation.assets){ res += key + '\n'; } res += 'fileList.txt'; compilation.assets['fileList.txt'] = { source: function () { return res; }, size: function () { return 1; } }; }) } } module.exports=TxtWebpackPlugin;
执行打包后dist目录下会输出fileLit.txt文件,内容:
main.js index.html fileList.txt
这样就完成了一个非常简单的plugin了