webpack

一、webpack介绍

webpack是静态模块打包器。webpack默认会通过 index.js 作为入口文件,并作为起点开始打包 。所有构建工具都是基于nodejs平台运行的,模块化默认采用commonjs规范。

二、安装webpack

使用webpack进行工程化开发,首先需要安装webpack。

1、在本地先全局安装webpack工具

npm install webpack@4 -g
npm install webpack-cli@3 -g

2、在当前项目中安装webpack

在当前项目里面初始化一个包的描述文件

npm init -y

在当前项目里安装webpack和webpack-cli

npm install webpack@4 -D
npm install webpack-cli@3 -D

三、设置入口文件

所有需要参与打包的文件,都应该在入口文件中引入。
可以设置main.js作为入口文件。

// 引入js文件
import './js/b.js'
// 引入css文件
import './css/a.css'

四、配置webpack

1、配置文件webpack.config.js

在项目根目录下创建一个 webpack.config.js 文件,然后 webpack 会自动使用它。webpack.config.js是webpack的配置文件。这里面只能使用commonjs模块化的规范。
作用:指示 webpack 干哪些活(当你运行 webpack 指令时,会加载里面的配置)

2、webpack五个核心概念

(1)entry入口

webpack 以哪个文件为入口起点开始打包。整个项目必须要指定一个打包的入口文件,默认为 ./src。

module.exports = {
    entry: './src/main.js'
}

(2)output输出

webpack 打包后的资源,项目打包后输出的目录。

// 引入path模块
const path = require('path');
module.exports = {
    output: {
        // 打包后的文件名
        filename: 'js/app.js',
        // 打包文件的输出路径,__dirname全局变量返回的是当前项目的绝对路径,dist是打包后文件保存的目录。
        path: path.resolve(__dirname, "dist")
    }
}

(3)loader加载器

让 webpack 能够去处理那些非 javascript 文件 (webpack自身只能处理javascript文件和json文件)。

(3.1)安装指定的loader

npm install file-loader@5.0.2 -D

(3.2)使用loader

通过module选项,配置加载器。

module.exports = {
    module: {
        rules: [
            // 每种对象处理一种文件
            // 处理图片文件
            {
                // 指定文件的格式,这里写的是正则格式
                test: /\.(png|jpe?g|gif)$/i,
                // 处理该文件,使用到了哪些loader
                use: [
                    {
                        loader: 'file-loader',
                    },
                ],
            }
        ]
    }
}

(4)plugins插件

可以用于执行范围更广的任务,功能比loader更强。配置选项是数组类型,表示可以使用很多插件。loader安装完后直接使用,但是plugins安装完后,需要先引入再使用。

(4.1)安装指定的插件

npm install html-webpack-plugin@3.2.0 -D

(4.2)引入插件

// 引入生成html页面的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');

(4.3)使用插件

module.exports = {
    plugins: [
        new HtmlWebpackPlugin()
    ]
}

(5)mode模式

采用什么方式打包,有两种方式:development开发模式,本地调试运行的环境;production生产模式,上线运行的环境)

module.exports = {
    mode: 'production'
}

3、使用webpack打包js文件

webpack默认可以处理js文件和json文件。所以不需要配置loader加载器。

(1)配置webpack.config.js

// 引入path模块
const path = require('path');
module.exports = {
    // 入口
    entry: './src/main.js',
    // 出口:项目打包后输出的目录
    output: {
        // 打包后的文件名
        filename: 'js/app.js',
        // 打包文件的输出路径
        path: path.resolve(__dirname, "dist")
    },
    // 模式:采用什么方式打包
    mode: 'production'
}

(2)执行打包命令

webapck

4、使用webpack打包css文件

webpack打包css文件,处理css文件使用css-loader和style-loader。打包的css文件直接存放在打包根目录中。
注意:use数组中loader的加载顺序是从右到左依次执行。所以一定要先写css-loader,再写style-loader。

(1)安装loader

npm install css-loader@3.4.2 -D
npm install style-loader@1.1.3 -D

(2)使用loader

module.exports = {
    module: {
        rules: [
            // 处理css文件
            {
                // 指定文件的格式
                test: /\.css$/i,
                // 从右到左依次执行,先写css-loader,再写style-loader
                use: ['style-loader', 'css-loader']
            },
        ]
    }
}

5、使用webpack打包时生成html文件

html-webpack-plugin插件在打包时,会自动帮我们创建一个html文件,并且将js引入。

(1)安装html-webpack-plugin插件

npm install html-webpack-plugin@3.2.0 -D

(2)引用插件

// 引入生成html页面的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');

(3)使用插件

module.exports = {
    plugins: [
        // 该插件在打包时,会自动帮我们创建一个html文件,并且将js引入。   
        // new HtmlWebpackPlugin()

        // 也可以指定一个html文件,作为页面模板被创建。
        new HtmlWebpackPlugin({
            // 指定html模板文件
            template: './public/index.html'
        }),
    ]
}

6、使用webpack打包图片文件

(1)打包图片文件file-loader

处理图片文件使用file-loader。但是不能限制需要打包的图片大小,以及不能指定打包后的图片存放路径。

(1.1)安装loader

npm install file-loader@5.0.2 -D

(1.2)使用loader

module.exports = {
    module: {
        rules: [
            // 处理图片文件
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        loader: 'file-loader',
                    },
                ]
            }
        ]
    }
}

2、使用webapck处理HTML中的图片

处理图片文件可以使用url-loader。可以配置打包后的文件路径以及文件名。还可以限制超过指定大小的图片参与打包,否则直接转为base64编码:单位是字节。
注意:url-loader默认采用的是ES6的模块化,html-loader采用的是commonjs模块化。为了让html模板中直接引入的图片可以正常显示,这里需要关闭ES6的模块化,统一采用commonjs模块化。

(2.1)安装loader

npm install url-loader@3.0.0 -D

(2.2)使用loader

module.exports = {
    module: {
        rules: [
            // 处理图片文件
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        // 指定具体的loader
                        loader: 'url-loader',
                        // 配置该loader的选项
                        options: {
                            // 指定打包后文件的名称
                            // 文件名([原文件名]_[随机返回hash值].[原扩展名])
                            // [name]表示采用文件原来的名称,[ext]表示采用文件原来扩展名,[hash:8]表示返回8位的哈希值
                            name: 'img/[name]_[hash:8].[ext]',
                            // 超过指定大小的图片参与打包。否则直接转为base64编码:单位是字节
                            limit: 1024 * 4,   // 超过4kb大小的图片参与打包
                            // 关闭es6的模块化,统一采用commonjs模块化
                            esModule: false
                        }
                    }
                ]
            },
            // 处理html文件中的img图片资源(负责引入img,从而能被url-loader进行处理)
            {
                test: /\.html$/i,
                use: {
                    loader: 'html-loader',
                    options: {
                        attrs: [':data-src']
                    }
                }
            }
        ]
    }
}

7、使用webapck打包时生成独立的css文件

mini-css-extract-plugin:把js中import导入的样式文件,单独打包成一个css文件,结合html-webpack-plugin,以link的形式插入到html文件中。

(1)安装mini-css-extract-piugin插件

npm install mini-css-extract-plugin@0.9.0 -D

(2)引用插件

// 引入生成html页面的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 引入独立生成css文件的插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

(3)使用插件

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/i,
                // 注意:这里用MiniCssExtractPlugin.loader去替换style-loader
                use: [{
                    // 指定具体的loader
                    loader: MiniCssExtractPlugin.loader,
                    // 配置选项
                    options: {
                        // 设置css文件中获取资源的路径时,往前多走一级,因为我们打包出来的css文件是放在指定的目录中
                        // 如果打包出来的css文件直接放在根路径,这个选项可以不设置   
                        publicPath: '../'     // 当前的css所在的文件相对于打包后的根路径dist的相对路径
                    }
                }, 'css-loader']
            }
        ]
    },
    plugins: [
        // 可以指定一个html文件,在打包时作为页面模板被创建。
        new HtmlWebpackPlugin({
            // 指定html模板文件
            template: './public/index.html'
        }),
        // 该插件在打包时,会将css文件独立出去
        new MiniCssExtractPlugin({
            // 可以指定css文件的输出路径
            filename: 'css/app.css'
        })
    ]
}

8、安装webpack-dev-server

(1)定义

开发服务器 :devServer:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)。
特点:只会在内存中编译打包,不会有任何输出。

(2)启动服务器

npx webpack-dev-server

(3)配置

module.exports = {
    devServer: {
        // 端口号
        port: 8866,
        // 自动打开页面
        open: true
    }
}

9、在webpack中引入Vue

vue-loader加载器:识别.vue组件。
vue-template-compiler:该模块可用于将 Vue 2.0 模板预编译为渲染函数(template => ast => render),以避免运行时编译开销和 CSP 限制。大都数场景下,与 vue-loader一起使用,只有在编写具有非常特定需求的构建工具时,才需要单独使用它。
VueLoaderPlugin插件:识别vue的单文件组件的插件。

(1)安装

npm install vue-loader@15.9.6 -D
npm install vue-template-compiler@2.6.12 -D
npm install vue@2.6.12 -S

(2)配置

(2.1)引入插件

// 引入处理vue文件的插件
const { VueLoaderPlugin } = require('vue-loader')

(2.2)使用插件

module.exports = {
    module: {
        rules: [
            // 处理vue文件
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    plugins: [
        // 用于识别vue的单文件组件的插件
        new VueLoaderPlugin()
    ]
}

(3)入口文件中导入Vue

注意:在工程化的环境中,引入的Vue是不带处理模板功能的,其实引入的是vue.runtime.esm.js,而不是完整的vue.js。所以必须要手动通过调用render函数的方式创建虚拟DOM并展示到页面中。

// 导入vue
import Vue from 'vue'
// 导入App组件
import App from './App.vue'
new Vue({
    el: '#app',
    // 渲染函数
    render: (h) => h(App)
})

10、在webpack中引入Element-UI

(1)安装element-ui

npm install element-ui@2.15.1 -S

(2)处理字体文件

导入element-ui组件库时,需要处理字体文件。

module.exports = {
    module: {
        rules: [
            // 导入element-ui组件库时,需要处理字体文件
            {
                test: /\.(ttf|woff)$/,
                use: [
                    {
                        loader: 'file-loader',
                        // 配置该loader的选项
                        options: {
                            // 指定打包后文件的名称
                            // 文件名([原文件名]_[随机返回hash值].[原扩展名])
                            name: 'font/[name]_[hash:8].[ext]'
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        // 用于识别vue的单文件组件的插件
        new VueLoaderPlugin()
    ]
}

(3)入口文件导入element-ui

// 引入element-ui组件库
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 因为element-ui组件库是一个插件,插件必须要通过Vue.use(插件名)引入
Vue.use(ElementUI);

(4)使用element-ui

从官网选择合适的组件代码,引入vue文件即可。

五、webpack中的其他配置

1、配置路径别名

module.exports = {
    // 配置路径别名
    resolve:{
       alias:{
           '@C':path.resolve(__dirname,'src/components')
       }
    }
}

例如:引入Home组件

// import Home from '../src/components/Home.vue'
import Home from '@C/Home.vue'

2、scripts

npm 允许在package.json文件里面,使用scripts字段定义脚本命令。
例如:
webpack 命令使用 npm run serve代替
npx webpack-dev-server 命令使用 npm run build代替

  "scripts": {
    "serve": "webpack",
    "build": "npx webpack-dev-server"
  }

六、完整配置

webapck.config.js配置文件

// 引入path模块(nodejs的内置模块,用于处理路径)
const path = require('path');
//导入清除插件
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
// 引入生成html页面的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 引入独立生成css文件的插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 引入处理vue文件的插件
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
    // 入口:整个项目必须要指定一个打包的入口文件,默认为 ./src。这里应用程序开始执行,webpack 开始打包
    entry: './src/main.js',
    // 出口:项目打包后输出的目录
    output: {
        // 打包后的文件名
        filename: 'js/app.js',
        // 打包文件的输出路径,__dirname全局变量返回的是当前项目的绝对路径,dist是打包后文件保存的目录。
        path: path.resolve(__dirname, "dist")
    },
    // loader:加载器,用来识别各种文件。
    // webpack默认只能处理js文件和json文件,如果要处理其他文件的话,需要引入对应的加载器。
    // 先安装加载器;通过module选项,配置加载器
    module: {
        // 在rules选项中,配置具体的加载器。该选项是一个数组,以为可能要处理很多种文件
        rules: [
            // 每种对象处理一种文件
            // 处理css文件
            // {
            //     // 指定文件的格式,这里写的是正则格式
            //     test: /\.css$/i,
            //     // 处理该文件,使用到了那些loader,这里我们使用到了css-loader和style-loader
            //     // 注意:use数组中loader的加载顺序是从右到左,从下到上依次执行。所以一定要先写css-loader,再写style-loader
            //     // css-loader:将css文件变成commonjs模块加载到js中
            //     // style-loader:创建style标签,将js中的样式资源插入进去
            //     use: ['style-loader', 'css-loader']
            // },
            {
                test: /\.css$/i,
                // 注意:这里用MiniCssExtractPlugin.loader去替换style-loader
                use: [{
                    // 指定具体的loader
                    loader: MiniCssExtractPlugin.loader,
                    // 配置选项
                    options: {
                        // 设置css文件中获取资源的路径时,往前多走一级,因为我们打包出来的css文件是放在指定的目录中
                        // 如果打包出来的css文件直接放在根路径,这个选项可以不设置   
                        publicPath: '../'     // 当前的css所在的文件相对于打包后的根路径dist的相对路径
                    }
                }, 'css-loader']
            },
            // 处理图片文件
            // {
            //     test: /\.(png|jpe?g|gif)$/i,
            //     use: [
            //         {
            //             loader: 'file-loader',
            //         },
            //     ],
            // },
            // 处理图片文件
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        // 指定具体的loader
                        loader: 'url-loader',
                        // 配置该loader的选项
                        options: {
                            // 指定打包后文件的名称
                            // 文件名([原文件名]_[随机返回hash值].[原扩展名])
                            // [name]表示采用文件原来的名称,[ext]表示采用文件原来扩展名,[hash:8]表示返回8位的哈希值
                            name: 'img/[name]_[hash:8].[ext]',
                            // 超过指定大小的图片参与打包。否则直接转为base64编码:单位是字节
                            limit: 1024 * 7,   //超过7kb大小的图片参与打包
                            // url-loader默认采用的是es6的模块化,html-loader采用的是commonjs模块化。
                            // 为了让html模板中直接引入的图片可以正常显示,这里需要关闭es6的模块化,统一采用commonjs模块化
                            esModule: false
                        }
                    }
                ]
            },
            // 处理html文件中的图片资源
            {
                test: /\.html$/i,
                use: {
                    loader: 'html-loader',
                    options: {
                        attrs: [':data-src']
                    }
                }
            },
            // 处理vue文件
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            // 导入element-ui组件库时,需要处理字体文件
            {
                test: /\.(ttf|woff)$/,
                use: [
                    {
                        loader: 'file-loader',
                        // 配置该loader的选项
                        options: {
                            // 指定打包后文件的名称
                            // 文件名([原文件名]_[随机返回hash值].[原扩展名])
                            name: 'font/[name]_[hash:8].[ext]'
                        }
                    }
                ]
            },
        ]
    },

    // plugins:插件,功能比loader更强大,用于处理复杂业务。配置选项是数组类型,表示可以使用很多插件。
    plugins: [
        // 重新打包时,清除之前打包文件的插件
        new CleanWebpackPlugin(),
        // 该插件在打包时,会自动帮我们创建一个html文件,并且将js引入。   
        // new HtmlWebpackPlugin()

        // 也可以制定一个html文件,作为页面模板被创建。
        new HtmlWebpackPlugin({
            // 指定html模板文件
            template: './public/index.html'
        }),
        // 该插件在打包时,会将css文件独立出去
        new MiniCssExtractPlugin({
            // 可以指定css文件的输出路径
            filename: 'css/app.css'
        }),
        // 用于识别vue的单文件组件的插件
        new VueLoaderPlugin()
    ],
    // 开发服务器相关
    // 开发服务器webpack-dev-server:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
    // 特点:只会在内存中编译打包,不会有任何输出
    // 启动devServer指令为:npx webpack-dev-server
    devServer: {
        // 端口号
        port: 8866,
        // 自动打开页面
        open: true
    },

    // 配置路径别名
    resolve:{
       alias:{
           '@C':path.resolve(__dirname,'src/components')
       }
    },

    // 模式:采用什么方式打包,有两种方式:开发模式(development),生产模式(production)
    mode: 'production'
}

main.js文件

// 导入vue
import Vue from 'vue'

// 引入element-ui组件库
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

// 导入App组件
import App from './App.vue'

new Vue({
    el: '#app',
    // 渲染函数
    render: (h) => h(App)
})

七、对应的webpack

npm install webpack@4.41.6 -D
npm install webpack-cli@3.3.11 -D
npm install css-loader@3.4.2 -D
npm install style-loader@1.1.3 -D
npm install file-loader@5.0.2 -D
npm install url-loader@3.0.0 -D
npm install html-loader@0.5.5 -D
npm install mini-css-extract-plugin@0.9.0 -D
npm install html-webpack-plugin@3.2.0 -D
npm install clean-webpack-plugin@3.0.0 -D
npm install webpack-dev-server@3.10.3 -D
npm install vue-loader@15.9.6 -D
npm install vue-template-compiler@2.6.12 -D
npm install vue@2.6.12 -S
npm install element-ui@2.15.1 -S
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容