现在webpack4出来了,需要重新记录一下webpack4的基本配置,为了以后节省新项目配置时间,很多东西一下子记不起来的时候,可以翻看下自己做的笔记,仅此而已。
如果你看到了这篇文章,说明你对webpack有兴趣,想了解webpack。如果一点都不懂,可以先看下API文档
https://www.webpackjs.com/concepts/
其实最好最全的文档就是官方提供的API文档,但是有很多地方,我们不知道怎么用,说话很官方。对于新手来说很难去理解。下面我把我理解的一些用法写出来,仅供大家参考:
要用webpack,首先需要下载,现在webpack4+以上版本下载webpack需要和webapck-cli一起下载使用,可以达到基础的零配置使用webpack
我们知道webpack运行环境是基于node的,所以使用webpack需要先安装nodejs。
安装
下载nodejs
下载nodejs直接去官网下载就行,官网链接:https://nodejs.org/en/
初始化项目
接下在我们就打开一个空的目录,随便你在哪里打开都可以。再用cmd工具进入到这个目录下,如果不知道cmd的基本用法可以百度或google一波基本操作。
webpack init
安装webpack
如果你使用 webpack 4+ 版本,你还需要安装 webapck-cli。现在下载安装webapck和webapck-cli,最好是下载到本地,可以避免多项目冲突问题。可以控制版本问题。更容易分别升级项目,不会影响其他项目
注意:如果下载不了,可以用淘宝的镜像下载,速度快,可以直接百度淘宝镜像设置,这里不解释了。
npm install webpack webpack-cli --save-dev
下载完可以看到node_modules文件夹和package-lock.json文件,说明下载成功
起步(基本演示代码)
简单demo
下面我们开始写一个简单demo,创建src目录,在src目录里面创建index.js
src(文件夹)
|-- idnex.js(文件)
index.js文件内容如下:
function context() {
const element = document.createElement('div');
element.innerHTML = 'Hello webpack';
return element;
}
document.body.appendChild(context());
webpack是零配置,所以现在就可以开始打包我们的index.js文件了,在cmd上运行代码:
npx webpack
这时候我们可以看到我们的文件里多出了dist文件夹,dist文件夹里有一个main.js文件。这个文件就是我们打包后的文件。 如果我们的js文件有依赖,我们下面代码用import引入一个js文件:
src(文件夹)
| -- index.js(文件)
| -- modu.js (文件)
修改index.js文件和添加modu.js文件:
index.js文件内容如下:
import modu from './module';
document.body.appendChild(modu());
添加modu.js文件内容如下:
function context() {
const element = document.createElement('div');
element.innerHTML = 'Hello webpack';
return element;
}
module.exports = context;
在cmd上运行代码:
npx webpack
这样也是可以打包成功的。
webpack零配置打包就已经好了,但是我们的项目不可能那么简单。
上面代码是很基础的代码。一般我们在项目中基本不会碰到那么简单的打包。没有用webpack真正的强大功能
js打包配置
问题来了,下面我们需要解决那些js打包问题
- 配置入口 ---- 单入口和多入口如何配置
- 配置出口 ---- 插件代码,公共代码,私有代码如何分离打包
- 代码缓存 ---- 如何添加哈希值
- 环境配置 ---- 配置测试环境和生成环境
- 编译代码 ---- 把浏览器不兼容的代码,比如typeSacript或者es6+代码编译成es5,做到浏览器能兼容
- 合并代码 ---- webpack默认代码合并
- 压缩混淆代码 ---- 配置生产模式,自动压缩文件,开发模式没有压缩
需要了解这些,我们就要手动创建一个webpack.config.js 配置文件
添加webpack.config.js 配置文件
在项目根目录手动创建一个webpack.config.js文件,添加如下代码:
const path = require('path');
module.exports = {
entry: {
app: './src/index.js',
},
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
}
};
所谓的webpack零配置,其实就是webapck默认配置就是上面的代码,你可以不配置
下面开始执行我们不用npx webpack来执行文件了,直接用npm来运行我们的配置,我们重新配置下package.json文件,在package.json文件配置我们的webpack打包命令,在package.json文件里,找到scripts,在里面添加命令如下:
"scripts": {
"start": "webpack --config webpack.config.js"
}
配置入口文件
- 配置单入口文件
module.exports = {
···
entry: {
app: './src/index.js', // 单入口文件,路径跟名字是可以自己随意修改
},
output: {
filename: 'main.js', // filename 是填写自己的文件名,也可以直接用[name].js
path: path.resolve(__dirname, 'dist') // path:需要填写路径。path.resolve()是nodejs的代码合并。__dirname是当前目录路径。'dist' 是根目录下的dist文件名。
}
···
};
- 配置多入口文件
const path = require('path');
module.exports = {
entry: { // 多入口文件需要以数组的形式传入
'index': ['./src/index.js'],
'modu': ['./src/modu.js'],
},
output: {
filename: '[name].js', // 如果是多入口文件,名字必须是[name].js
path: path.resolve(__dirname, 'dist')
}
};
···
};
配置出口文件
- 配置单出入口文件
module.exports = {
···
entry: {
app: './src/index.js', // 单入口文件,路径跟名字是可以自己随意修改
},
output: {
filename: 'main.js', // filename 是填写自己的文件名,也可以直接用[name].js
path: path.resolve(__dirname, 'dist') // path:需要填写路径。path.resolve()是nodejs的代码合并。__dirname是当前目录路径。'dist' 是根目录下的dist文件名。
}
···
};
- 配置多出口文件
const path = require('path');
module.exports = {
entry: { // 多入口文件需要以数组的形式传入
'index': ['./src/index.js'],
'modu': ['./src/modu.js'],
},
output: {
filename: '[name].js', // 如果是多出口文件,名字必须是[name].js
path: path.resolve(__dirname, 'dist')
}
};
···
};
- 公共代码,私有代码分离
如果你使用了多入口打包文件,在两个js文件里引入的同一个文件,这个时候就会重复打包js文件,为了避免重复打包需要改一下配置:
const path = require('path');
module.exports = {
entry: { // index.js和modu.js 都引用了同一个jquery.js (import $ from 'jquery';)
'index': ['./src/index.js'],
'modu': ['./src/modu.js'],
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: { // vendor名字随意取都可以
test: /node_modules/, // 匹配相应文件夹下的模块
chunks: "all", // 匹配的块的类型:initial(初始块),async(按需加载的异步块),all(所有块)
name: "main", // 输出的js名字,可以随意修改
priority: 10, // 设置优先级,分离规则的优先级,优先级越高,则优先匹配
enforce: true,
minChunks :2 // 分离前,该块被引入的次数
}
}
}
}
};
打包出来后。可以在dist看到3个js。分别是index.js,main.js,modu.js
- 插件代码,配置下载第三方库
- 直接npm下载,然后引入,这样会有一个问题,如果每个页面都需要使用的话,就需要在每一个每页都手动引用,太麻烦
import $ from 'jquery';
const b = '2'
$('body').append(b);
- ProvidePlugin配置,全局配置,一次管够
const webpack = require('webpack');
plugins:[
new webpack.ProvidePlugin({
$:'jquery' //下载Jquery库
})
]
代码缓存
浏览器缓存机制,在很多时候,我们需要清除缓存,最直接的办法就是修改文件引用路径,所以在打包出来的文件名添加哈希值,修改上面配置:
用下面几种方法配置:
[hash] ---- 模块标识符(module identifier)的 hash
[chunkhash] ---- chunk 内容的 hash
[id] ---- 模块标识符(module identifier)
[query] ---- 模块的 query,例如,文件名 ? 后面的字符串
[contenthash] ---- 自己模块的内容变化,那么hash值才改变
const path = require('path');
module.exports = {
entry: {
'index': ['./src/index.js'],
'modu': ['./src/modu.js'],
},
output: {
filename: '[name].[chunkhash].js', // 添加hash值
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: { // vendor名字随意取都可以
test: /node_modules/, // 匹配相应文件夹下的模块
chunks: "all", // 匹配的块的类型:initial(初始块),async(按需加载的异步块),all(所有块)
name: "main", // 输出的js名字
priority: 10, // 设置优先级,分离规则的优先级,优先级越高,则优先匹配
enforce: true,
minChunks :2 // 分离前,该块被引入的次数
}
}
}
}
};
打包出来后,我们可以看到到文件名发生变化了
环境配置(模式配置)
webpack 增加了模式区分,有生产环境和开发环境两种打包方式
- development:开发模式,打包默认不压缩代码,默认开启代码调试
- production:生产模式,上线时使用,打包压缩代码,不开启代码调试。
- 通过在配置文件中添加mode配置项进行模式选择
module.exports = {
mode: 'development',
};
- 通过配置package.json文件 进行模式切换:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --config webpack.config.js --mode production", // 生产模式
"start:dev": "webpack --config webpack.config.js --mode development" // 开发模式
},
编译代码
把es6+ 的代码转义成es5的代码,解决浏览器兼容问题,需要下载Babel-loader来实现
webpack4 + 下载:
npm install -D babel-loader @babel/core @babel/preset-env
添加 babel-loader 到 module 的 loaders 列表中
module.exports = {
module: {
rules: [{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}],
},
};
html打包
打包html需要下载html-webpack-plugin插件:
npm install html-webpack-plugin --save-dev
在webpack.config.js文件引用插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
···
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 默认储存到dist文件夹目录下
}),
]
···
}
如果需要引入模板:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
···
module: {
rules: [
{
test: /\.html$/,
use: [ {
loader: 'html-loader',
options: {
minimize: true
},
}],
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 默认储存到dist文件夹目录下
template: 'index.html', // 添加html模板
cache: false, // 清除缓存
hash: true // 添加哈希值
}),
]
···
}
指定引入多出口的js文件:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
···
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 默认储存到dist文件夹目录下
template: 'index.html', // 添加html模板
cache: false, // 清除缓存
hash: true, // 添加哈希值
chunks: ['modu'] // 值与entry中的key对应
}),
new HtmlWebpackPlugin({
filename: 'modu.html', // 默认储存到dist文件夹目录下
template: 'modu.html', // 添加html模板
cache: false, // 清除缓存
hash: true, // 添加哈希值
chunks: ['modu'] // 值与entry中的key对应
}),
]
···
}
css独立打包
npm install mini-css-extract-plugin --save-dev
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [{ // 加载样式
test: /\.(sa|sc|c)ss$/,
use: [{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
],
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'asset/css/index.css', // 指定出口
}),
],
};
字体打包
module: {
rules: [
{ // 加载字体
test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[contenthash:8].[ext]', // name:文件名,contenthash:哈希,:8:哈希的长度吗,[ext]:文件后缀
outputPath: 'asset/fonts/', // 打文件打包路径
},
},
]
},
图片打包
module: {
rules: [
{ // 加载图片
test: /\.(png|jpg|gif)$/,
loader: 'file-loader',
options: {
esModule: false, // 这里设置为false
name: '[name].[contenthash:8].[ext]', // name:文件名,contenthash:哈希,:8:哈希的长度吗,[ext]:文件后缀
outputPath: 'asset/img/', // 打文件打包路径
},
},
]
},
资源文件如果打包时,路径不统一可以使用绝对路径:
module.exports = {
output: {
publicPath: 'http://localhost:7788/', // html模板里的img图片前缀
},
}
若要开启代码调试可在配置文件中增加devtool配置项
devtool: "source-map"
开发中 Server(代码热更新)
npm install webpack-dev-server --save-dev
// webpack.config.js 文件配置
module.exports = {
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: true,
port: 9000,
open: true
}
}
// package.json文件配置
"scripts": {
"start:dev": "webpack-dev-server"
},
vue 常见问题
打包vue代码的时候出现如下报错:You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
答:处理文件链接:https://vue-loader.vuejs.org/zh/guide/#vue-cli
vue引入插件方法
安装:
npm install xxxx --save
// main.js中引入:
import yyy from 'xxxx'
Vue.use(yyy)
网友评论