webpack
官方解释
从本质上来讲,webpack是一个现在的javaScript应用的静态模块化打包工具。(从两点概括这句话即模块和打包)
前端模块化
- 前端模块化的一些方案:AMD、CMD、CommonJS、ES6(浏览器不能识别它们,但是webpack可以做它们的底层支撑,方可进行模块化开发)
- ES6之前,要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。
- 并且在通过模块化开发完成了项目后,还需要处理模块化间的各种依赖,并且将其进行整合打包。
- 此时出现webpack,其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
- 不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用。
打包
- webpack可以帮助我们进行模块化,并且处理模块间的各种复杂关系后,打包的概念就很好理解了。
- 将webpack中的各种资源模块进行打包合并成一个多个包(Bundle)
- 打包的过程中,还可对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。
- 打包工具还有grunt/gulp。
webpack的安装
wepack为了正常运行必须依赖node环境,而node环境为了可以正常的执行,必须使用npm工具管理node中各种依赖的包。
因此安装webpack首先要安装Node.js,Node.js自带了软件包管理工具npm。
全局安装webpack。
npm install webpack@3.6.0 -g
局部安装webpck。 –save-dev是开发时依赖,项目打包后不需要继续使用。
npm install webpack@3.6.0 --save-dev
webpack的配置
文件和文件夹解析
- dist文件夹:用于存放之后打包的文件
- src文件夹:用于存放我们写的源文件
- main.js:项目的入口文件。
- mathUtils.js:定义了一些数学工具函数,可以在其他地方引用,并且使用。
- index.html: 浏览器打开展示的首页html(在这里引用的是src内最终打包的文件即dist文件夹的内容)。
- package.json:通过npm init生成的,npm包管理的文件。
JS打包
在webpack目录下创建配置文件webpack.config.js
js
const path = require("path"); //Node.js内置模块
module.exports = {
entry: './src/main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出文件
}
}
读取当前项目目录下src文件夹中的main.js(入口文件)内容,分析资源依赖,把相关的js文件打包,打包后的文件放入当前目录的dist文件夹下,打包后的js文件名为bundle.js
entry: 为打包的入口
output: 为打包的出口
html打包
npm install html-webpack-plugin --save-dev
js
const path = require("path"); //Node.js内置模块
module.exports = {
entry: './src/main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出文件
},
plugins: [
new HtmlWebpackPlugin({
title: '首页', //生成的页面标题<head><title>首页</title></head>
filename: 'index.html', // dist目录下生成的文件名
template: './src/index.html' // 我们原来的index.html,作为模板
})
]
}
css打包
安装style-loader和 css-loader
Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。
Loader 可以理解为是模块和资源的转换器。
npm install --save-dev style-loader css-loader
修改webpack.config.js
jsconst path = require("path"); //Node.js内置模块 module.exports = { entry: './src/main.js', //配置入口文件 output: { path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径 filename: 'bundle.js' //输出文件 }, module: { rules: [ { test: /\.css$/, //打包规则应用到以css结尾的文件上 use: ['style-loader', 'css-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ title: '首页', //生成的页面标题<head><title>首页</title></head> filename: 'index.html', // dist目录下生成的文件名 template: './src/index.html' // 我们原来的index.html,作为模板 }) ] }
less打包
安装style-loader和 css-loader之外还需安装less-loader
js
const path = require("path"); //Node.js内置模块
module.exports = {
entry: './src/main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出文件
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '首页', //生成的页面标题<head><title>首页</title></head>
filename: 'index.html', // dist目录下生成的文件名
template: './src/index.html' // 我们原来的index.html,作为模板
})
]
}
sass打包
与less打包一致。
js
const path = require("path"); //Node.js内置模块
module.exports = {
entry: './src/main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出文件
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '首页', //生成的页面标题<head><title>首页</title></head>
filename: 'index.html', // dist目录下生成的文件名
template: './src/index.html' // 我们原来的index.html,作为模板
})
]
}
图片文件处理
js
module.exports = {
entry: './src/main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出文件
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
// {
//将图片打包到发布环境中的images目录下
// test: /\.(jpg|jpeg|gif|png|svg)$/,
// use: {
// loader: 'url-loader',
// options: {
// limit: 1024 * 1,
// name: 'images/[hash:8].[ext]',
// publicPath: 'dist/'
// }
// }
// 新版webpack打包
{
//将图片打包到发布环境中的images目录下
test: /\.(jpg|jpeg|gif|png|svg)$/,
type: 'asset/images'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '首页', //生成的页面标题<head><title>首页</title></head>
filename: 'index.html', // dist目录下生成的文件名
template: './src/index.html' // 我们原来的index.html,作为模板
})
]
}
- limiet的意思是:图片大小小于limit时,使用base64转码。大于limit时,正常打包。
- name:通过name属性改变图片的打包目录和文件名。
- hash:图片经过处理后,会在输出文件夹中生成图片,此时图片的名字为hash。ext代表图片的格式。
- publicPath:为你的文件配置自定义 public 发布目录。
- outputPath:为你的文件配置自定义 output输出目录 。
ES6转ES5
webpack并不能将ES6语法转化成ES5语法,因此我们需要使用babel转化,webpack可以直接使用babel的loader。
安装babel-loader
npm install --save-dev babel-loader @babel/core @babel/preset-env
配置
jsconst path = require("path"); //Node.js内置模块 module.exports = { entry: './src/main.js', //配置入口文件 output: { path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径 filename: 'bundle.js' //输出文件 }, module:{ rules:[ { test:/\.css$/, use:['style-loader','css-loader'] }, { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, { //将图片打包到发布环境中的images目录下 test: /\.(jpg|jpeg|gif|png|svg)$/, use: { loader: 'url-loader', options: { limit: 1024 * 1, name: 'images/[hash:8].[ext]', publicPath: 'dist/' }, }, }, { test:/\.js$/, //已作为js扩展名这样类型的文件 exclude:/node_modules/, //排除node_modules文件夹 use:{ loader:'babel-loader', //转换成es5 options:{ presets:['@babel/preset-env'], //设置编译的规则 } } } ] }, plugins: [ new HtmlWebpackPlugin({ title: '首页', //生成的页面标题<head><title>首页</title></head> filename: 'index.html', // dist目录下生成的文件名 template: './src/index.html' // 我们原来的index.html,作为模板 }) ] }
- 但是这样直接打包会失败 因为目前还解析不了我们的async/await语法
- 需要安装一个
regeneratorRuntime
环境
regeneratorRuntime插件
npm install --save-dev @babel/runtime //包含了regeneratorRuntime运行时候需要的内容
npm install --save-dev @babel/plugin-transform-runtime // 这个插件 在需要regeneratorRuntime的地方自动导入包 就是在需要的时候会自动运行他
jsconst path = require("path"); //Node.js内置模块 module.exports = { entry: './src/main.js', //配置入口文件 output: { path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径 filename: 'bundle.js' //输出文件 }, module:{ rules:[ { test:/\.css$/, use:['style-loader','css-loader'] }, { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, { //将图片打包到发布环境中的images目录下 test: /\.(jpg|jpeg|gif|png|svg)$/, use: { loader: 'url-loader', options: { limit: 1024 * 1, name: 'images/[hash:8].[ext]', publicPath: 'dist/' }, } }, { test:/\.js$/, //已作为js扩展名这样类型的文件 exclude:/node_modules/, //排除node_modules文件夹 use:{ loader:'babel-loader', //转换成es5 options:{ presets:['@babel/preset-env'], //设置编译的规则 plugins:[ // 设置编译的插件 ['@babel/plugin-transform-runtime'] //设置编译的规则 ] } } } ] }, plugins: [ new HtmlWebpackPlugin({ title: '首页', //生成的页面标题<head><title>首页</title></head> filename: 'index.html', // dist目录下生成的文件名 template: './src/index.html' // 我们原来的index.html,作为模板 }) ] }
配置vue
js
const path = require("path"); //Node.js内置模块
module.exports = {
entry: './src/main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出文件
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
//将图片打包到发布环境中的images目录下
test: /\.(jpg|jpeg|gif|png|svg)$/,
use: {
loader: 'url-loader',
options: {
limit: 1024 * 1,
name: 'images/[hash:8].[ext]',
publicPath: 'dist/'
},
}
},
{
test:/\.js$/, //已作为js扩展名这样类型的文件
exclude:/node_modules/, //排除node_modules文件夹
use:{
loader:'babel-loader', //转换成es5
options:{
presets:['@babel/preset-env'], //设置编译的规则
plugins:[ // 设置编译的插件
['@babel/plugin-transform-runtime'] //设置编译的规则
]
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '首页', //生成的页面标题<head><title>首页</title></head>
filename: 'index.html', // dist目录下生成的文件名
template: './src/index.html' // 我们原来的index.html,作为模板
})
],
resolve: {
// alias: 别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
// 设置可以导入的模块后缀
extensions: ['.ts', '.js']
}
}
配置vue相关loader
npm install --save-dev vue-loader vue-template-complier
js
const path = require("path"); //Node.js内置模块
module.exports = {
entry: './src/main.js', //配置入口文件
output: {
path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' //输出文件
},
module:{
rules:[
{
test: /\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
//将图片打包到发布环境中的images目录下
test: /\.(jpg|jpeg|gif|png|svg)$/,
use: {
loader: 'url-loader',
options: {
limit: 1024 * 1,
name: 'images/[hash:8].[ext]',
publicPath: 'dist/'
},
}
},
{
test: /\.js$/, //已作为js扩展名这样类型的文件
exclude: /node_modules/, //排除node_modules文件夹
use: {
loader:'babel-loader', //转换成es5
options: {
presets: ['@babel/preset-env'], //设置编译的规则
plugins: [ // 设置编译的插件
['@babel/plugin-transform-runtime'] //设置编译的规则
]
}
}
},
{
test: /\.vue$/,
use: ['vue-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
title: '首页', //生成的页面标题<head><title>首页</title></head>
filename: 'index.html', // dist目录下生成的文件名
template: './src/index.html' // 我们原来的index.html,作为模板
})
],
resolve: {
// alias: 别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}