两种安装方式
1.项目中安装
npm i webpack webpack-cli -D
2.全局
npm i webpack webpack-cli -g
安装成功后可以使用npx webpack 执行当前项目中的webpack
如果安装的是全局的可以直接 webpack
默认会去当前找当前目录下的src文件夹中的index.js
执行完后会在和src同级,也就是项目目录下生成一个dist目录,里面会生成一个main.js
webpack的四大核心模块
- 入口(entry): 程序的入口js
- 输出(output): 打包后存放的位置
- loader: 用于对模块的源代码进行转换
- 插件(plugins): 插件目的在于解决 loader无法实现的其他事
配置webpack.config.js (使用cjs规范)
**
const path = require('path')module.exports = {// 入口文件配置entry: './src/mian.js', //指定入口文件// 出口文件配置项output: {// 输出的路径,webpack2起就规定必须是绝对路径path: path.join(__dirname, 'dist'),// 输出文件名字filename: 'bundle.js'},mode: 'development' // 默认为production, 可以手动设置为development, 区别就是是否进行压缩混淆}
将npx webpack命令配置到package.json的脚本中
运行npm run build
"scripts": {"build": "webpack","build2": "webpack --config mywebpack.confing.js" // 可以自定义打包的文件这里就可以不是webpack.config.js了,可以设置在不同环境下打包的时候有不同的配置项// 不过这个自定义的打包文件也要遵循规范只不多就是可以换个名字},
开发时自动编译工具
每次要编译代码时,手动运行 npm run build 就会变得很麻烦。
webpack 中有几个不同的选项,可以帮助你在代码发生变化后自动编译代码:
- webpack’s Watch Mode
- webpack-dev-server
- webpack-dev-middleware
多数场景中,可能需要使用 webpack-dev-server,但是不妨探讨一下以上的所有选项。
watch
在webpack指令后面加上--watch参数即可
主要的作用就是监视本地项目文件的变化, 发现有修改的代码会自动编译打包, 生成输出文件
- 配置
package.json的scripts"watch": "webpack --watch" - 运行
npm run watch
还可以通过配置文件对watch的参数进行修改:
const path = require('path')module.exports = {// 入口文件配置entry: './src/mian.js', //指定入口文件// 出口文件配置项output: {// 输出的路径,webpack2起就规定必须是绝对路径path: path.join(__dirname, 'dist'),// 输出文件名字filename: 'bundle.js'},watch: true, // 改变这里为truemode: 'development' // 默认为production, 可以手动设置为development, 区别就是是否进行压缩混淆}
webpack-dev-server (推荐)
安装devServer:devServer需要依赖webpack,必须在项目依赖中安装webpacknpm i webpack-dev-server webpack -D
这里注意 这个插件有时候会和webpack又不兼容的问题
所以推荐下面的一套版本.不会出现版本之间不兼容的问题
"devDependencies": {"webpack": "^4.30.0","webpack-cli": "^3.3.1","webpack-dev-server": "^3.3.1"}
- 运行:
npx webpack-dev-server - 运行:
npx webpack-dev-server --hot --open --port 8090 配置package.json的scripts:"dev": "webpack-dev-server --hot --open --port 8090"
<br />devServer会在内存中生成一个打包好的bundle.js,专供开发时使用,打包效率高,修改代码后会自动重新打包以及刷新浏览器,用户体验非常
默认会自动开启一个服务器去托管我们的项目,寻找根目录下的index.html打开.同时会自动导入那个bundle.js。也就是那个虚拟的在内存中的
这个也可以更改 --contentBase src"dev": "webpack-dev-server --conentBase src --hot --open --port 8090"
还可以通过配置文件对devServer的参数进行修改:
const path = require('path')module.exports = {// 入口文件配置entry: './src/mian.js', //指定入口文件// 出口文件配置项output: {// 输出的路径,webpack2起就规定必须是绝对路径path: path.join(__dirname, 'dist'),// 输出文件名字filename: 'bundle.js'},devServer: {port: 8090,open: true,hot: true,contentBase:'./src' // 改变根目录},watch: true, // 改变这里为truemode: 'development' // 默认为production, 可以手动设置为development, 区别就是是否进行压缩混淆}
html插件
- 安装html-webpack-plugin插件npm i html-webpack-plugin -D
- 在webpack.config.js中的plugins节点下配置 ```javascript
const HtmlWebpackPlugin = require(‘html-webpack-plugin’)
plugins: [ new HtmlWebpackPlugin({ filename: ‘index.html’, template: ‘template.html’ // 模板html 会根据这个模板生成html }) ]
1. devServer时根据模板在e项目根目录下生成html文件(类似于devServer生成内存中的bundle.js)<br />1. devServer时自动引入bundle.js放入这个html文件中<br />1. 如果执行打包时会在设置的出口文件夹自动生成index.html和bundles.js 并且会自动把这个js导入不过要注意的是在执行build后,html文件中导入的是dist文件夹下的bundls.js。此时会把dist当成一个项目根目录。所以我们如果想打开生产的index.html 需要把这个文件夹以服务起的形式托管为静态资源(可以参考我的项目打包里的步骤,在项目打包这个知识库中)<a name="0Few4"></a>## 处理css为了方便打包。所以在入口的js文件中使用import导入css文件。这样的话方便操作。因为这个js文件收我们的入口js文件1. 安装npm i css-loader style-loader -D1. 配置webpack.config.js```javascriptmodule: {rules: [// 配置的是用来解析.css文件的loader(style-loader和css-loader){// 用正则匹配当前访问的文件的后缀名是 .csstest: /\.css$/,use: ['style-loader', 'css-loader'] // webpack底层调用这些包的顺序是从右到左}]}
loader的释义:
- css-loader: 解析css文件
- style-loader: 将解析出来的结果 放到html中, 使其生效
最好如果你打开页面会发现。并没有单独的导入某个css文件。而是利用js文件。在html中动态的生成了style标签的形式加载样式
处理less 和 sass
npm i less less-loader sass-loader node-sass -D
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
{ test: /\.s(a|c)ss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
]
}
处理图片
npm i file-loader url-loader -D
url-loader封装了file-loader, 所以使用url-loader时需要安装file-loader
{
test: /\.(png|jpg|gif)/,
use: [{
loader: 'url-loader',
options: {
// limit表示如果图片大于5KB,就以路径形式展示,小于的话就用base64格式展示
limit: 5 * 1024,
// 打包输出目录
outputPath: 'images',
// 打包输出图片原来名称,
name: '[name]-[hash:4].[ext]'
}
}]
}
babel
npm i babel-loader @babel/core @babel/preset-env -D
如果需要支持更高级的ES6语法, 可以继续安装插件:npm i @babel/plugin-proposal-class-properties -D
也可以根据需要在babel官网找插件进行安装
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/env'], /// 语法预设
plugins: ['@babel/plugin-proposal-class-properties'] //
}
},
exclude: /node_modules/ // 不需要转换依赖包
}
官方更建议的做法是在项目根目录下新建一个.babelrc的babel配置文件
{
"presets": ["@babel/env"],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
如果需要使用ES6/7中对象原型提供的新方法,babel默认情况无法转换,即使用了transform-runtime的插件也不支持转换原型上的方法
需要使用另一个模块: npm i @babel/polyfill -S
该模块需要在使用新方法的地方直接引入: import '@babel/polyfill'
插件
clean-webpack-plugin
该插件用于在你每次npm run build 打包项目的时候首先清楚dist文件夹再重新生成
npm i clean-webpack-plugin -D
const CleanWebpackPlugin = require('clean-webpack-plugin')
使用
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html'
}),
new CleanWebpackPlugin()
],
copy-webpack-plugin
当我们在使用一些静态资源的时候,如果引入的静态资源不是在src文件夹内部。而是和src文件夹平级的,或者是项目的根目录下。那么在开发的时候或许没有什么问题。但是在npm run build打包之后。因为这时候的引入会变成项目根目录,而不是src内部的文件不会参与打包。会导致文件丢失,不显示的情况。
这个插件会把我们copy一份原来的文件放在dist文件中。所有建议大家在使用该插件的时候。在项目的根目录专门创建一个文件夹 static用来存放一些静态的资源,比如文件,字体图标啥的
npm i copy-webpack-plugin -D
const CopyWebpackPlugin = require('copy-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html'
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin([
{
from: path.join(__dirname, 'assets'),
to: 'assets'
}
])
],
from: 源, 从哪里拷贝, 可以是相对路径或绝对路径, 推荐绝对路径
to: 目标, 拷贝到哪里去, 相对于output的路径, 同样可以相对路径或绝对路径, 但更推荐相对路径(直接算相对dist目录即可) —之这里回去找我们output设置的输出项目打包后的输出路径
BannerPlugin
这是一个webpack的内置插件不需要下载,直接使用用于给打包的JS文件加上版权注释信息
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html'
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin([
{
from: path.join(__dirname, 'assets'),
to: 'assets'
}
]),
new webpack.BannerPlugin('看到这不点赞????!')
],
