Webpack入门笔记

    技术2022-07-11  95

    目录

    (一) Webpack 概述(二) Webpack 基本使用1. node 安装2. Webpack 安装3. webpack 简单使用 (三) webpack 配置文件(四) loader1. loader-css 文件处理2. loader-图片文件处理3. loader-ES6转ES5 (五) Webpack集成Vuejs(六) Plugin1. BannerPlugin2. html-webpack-plugin3. uglifyjs-webpack-plugin (七) Webpack 搭建本地服务器

    (一) Webpack 概述

    Webpack: 是一个现代的JavaScript应用的静态模块打包器, 这是Webpack官方的解释.在这句话中提到两个关键字:

    模块: 在JavaScript发展初期就是为了实现简单的页面交互逻辑, 但随着前端技术不断更新、迭代, CPU、浏览器性能得到了极大的提升, 导致前端页面逻辑复杂, 代码日益膨胀. 此时就会考虑使用模块化规范去管理代码:

    将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信模块化规范: CommomJS、ES6、AMD、CMDWebpack其中一个核心: 让开发者尽可能用模块化开发, 并且会帮助我们处理模块间的依赖关系, 更甚的是: 不仅仅是JS文件, CSS、图片、JSON文件都会当做模块来使用

    打包: Webpack帮助项目模块化, 并且处理模块间的各种复杂关系后, 就会对项目中各种资源模块进行打包合成一个或多个包. 在打包的过程中, 还可以对资源进行处理, 比如压缩图片, 将scss转换成css, 将ES6语法转成ES5语法, 将TypeScript转成JavaScript等等操作

    (二) Webpack 基本使用

    Webpack使用依赖着node环境, 而node环境运行需要各种依赖的包, 为了简化手动管理包的成本, 诞生npm工具(node package manager 软件包管理工具).

    1. node 安装

    node下载链接: https://nodejs.org/zh-cn/download/

    查看安装的node版本: cmd中输入命令 node -v

    2. Webpack 安装

    全局安装webpack: npm install webpack@3.6.0 -g

    查看安装的webpack版本: webpack --version

    局部安装webpack: 在项目文件目录下执行: npm install webpack@3.6.0 --save-dev (开发时依赖, 运行时不依赖webpack)

    在终端上直接执行webpack命令, 使用的是全局安装的webpack当在 package.json 中定义了scripts时, 其中包含了webpack命令, 那么此时使用的是局部webpack

    3. webpack 简单使用

    对模块化的js文件打包, 新建文件目录: main.js: 模块文件入口, 此模块不会依赖其他模块, 只会导入其他模块. Webpack会对入口文件打包, 且自动处理模块间的依赖关系

    // 使用CommonJs的模块化规范: 导入 const {sum, mul} = require('./mathUtils.js') // 使用ES6的模块化规范: 导入 import {name, age, height} from './info' console.log(sum(10, 20)) console.log(mul(10, 20)) console.log(name) console.log(age) console.log(height)

    mathUtils.js: 数学工具模块

    function sum(num1, num2) { return num1 + num2 } function mul(num1, num2) { return num1 * num2 } // 使用CommonJs的模块化规范: 导出 module.exports = { sum, mul }

    info.js: 信息模块

    const name = "zhang san" const age = 22 const height = 1.88 // 使用ES6的模块化规范: 导出 export {name, age, height}

    对 main.js 模块入口文件打包: 终端进入到项目目录下, 执行打包命令

    webpack 要打包的(入口)模块文件路径 打包后生成文件的存储路径 webpack ./src/main.js ./dist/bundle.js

    inde.html: 引入打包后生成的js文件

    <body> <script src="./dist/bundle.js"></script> </body>

    (三) webpack 配置文件

    webpack 配置文件分为两种: webpack.config.js 和 package.json, 简化打包代码

    在项目文件夹目录下新建webpack.config.js, 并添加js内容

    const path = require('path') // 动态获取文件的绝对路径需要借助node语法, path对象从node包中导入, 必须先执行 npm init, 会在当前目录下生成package.json文件 module.exports = { entry: './src/main.js', // entry 打包的入口文件: 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始 output: { // output: 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件 path: path.resolve(__dirname, 'dist'), // 打包后文件存储绝对路径 filename: 'bundle.js' // 打包后文件名称 } }

    此时, 可以直接用命令 webpack 打包, 无需指定入口和出口文件

    在package.json 文件的sripts脚本中, 可以将 任意命令(npm run build) 映射成 webpack命令, 终端直接执行npm run build命令, 相当于执行了 webpack命令.

    还有一点, 在终端使用webpack命令操作都是全局webpack, 使用脚本执行映射的命令, 会优选选用局部webpack. 局部安装webpack: 在项目文件目录下执行:

    npm install webpack@3.6.0 --save-dev (开发时依赖, 运行时不依赖webpack) { "name": "webpack", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" // 将 npm run build 映射成 webpack命令 }, "author": "", "license": "ISC" }

    (四) loader

    loader: loader是一种打包方案, 用于对模块的源代码进行转换.

    webpack 默认只会对js代码进行打包处理, 对其他文件(css, png…)是无法打包的. 但可以通过给webpack扩展对应的loader, 可以实现: 对css、图片打包处理, 也包括一些高级的将ES6转成ES5代码, 将TypeScript转成JavaSciprt, 将scss、less转成css、将.jsx、.vue文件转成js文件等等

    loader使用

    通过npm安装需要使用的loader, 可通过官网查询对应的loader: https://www.webpackjs.com/loaders/在webpack.config.js中的module关键字下进行配置

    1. loader-css 文件处理

    在scr下创建css文件夹, 添加normall.css文件

    body { background-color: red; }

    在入口main.js文件引入(依赖)

    // 使用CommonJs的模块化规范: 导入(依赖)css文件 require('./css/normal.css')

    安装style-loader(将模块的导出作为样式添加到 DOM 中)、css-loader(解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码)

    npm install style-loader --save-dev npm install --save-dev css-loader

    在webpack.config.js中的module关键字下进行配置

    module.exports = { module: { rules: [ { test: /\.css$/, /* css-loader 只负责jiangcss文件进行加载 style-loader 只负责将样式添加到DOM中 使用多个loader时, 是从右向左读取的顺序 */ use: [ 'style-loader', 'css-loader' ] } ] } }

    重新打包运行

    2. loader-图片文件处理

    修改css样式(normal.css)body { background: url('../img/small.jpg'); } 在入口main.js文件引入(依赖)安装 url-loadernpm install --save-dev url-loader 在webpack.config.js中的module.rules添加配置{ test: /\.(png|jpg|gif)$/, use: [{ loader: 'url-loader', options: { // 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式 // 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载 limit: 16000, // 打包后文件存储路径/[图片原名称].[取hash值前8位].[扩展名] (大于limit时,才会生效) name: 'img/[name].[hash:8].[ext]' } }] } 重新编译

    图片(文件)字节数大于limit时, 需要安装新的loder: file-loader

    npm install --save-dev file-loader

    使用 file-loader打包, 会生成一个打包后的文件, 且需要存储到dis/name(上文配置的name), 同时还需要修改webpack.config.js

    output: { path:path.resolve(__dirname, 'dist'), // 打包后文件存储绝对路径 filename: 'bundle.js', // 打包后文件名称 publicPath: 'dist/' // 输出解析文件的目录,指定资源文件引用的目录 },

    3. loader-ES6转ES5

    webpack打包生成的bundle.js中, 默认的打包方式不会将ES6语法转换成ES5语法 有些浏览器是不支持ES6的语法的, 因此, 我们希望webpack打包过程中将ES6语法转换成ES5语法, 需要借助 babel-loader加载器

    npm install --save-dev babel-loader@7 babel-core babel-preset-es2015 { test: /\.js$/, // 排除 node_modules, bower_components的js文件 exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['es2015'] } } }

    (五) Webpack集成Vuejs

    安装vuejs的依赖

    npm install vue --save // 开发时依赖, 运行时也依赖

    在main.js 导入Vue的依赖, 会在node_modules文件中查找

    // 使用ES6的模块化规范: 导入vue, 在node_modules文件中查找依赖 import Vue from 'vue' const app = new Vue({ el: '#app', data() { return { message: 'Hello, Webpack!!' } } })

    在index.html中 创建挂彩元素(template)

    <div id="app"> <h3>{{message}}</h3> </div> <script src="./dist/bundle.js"></script>

    此时重新编译运行, 控制台报错: 产生这个原因的错误是因为: Vue最终构建发布版时, 构建了两个版本

    运行时版本(runtime-noly): 在运行时版本中, 项目代码中不能有任何的template属性, 无法编译编译版本(runtime-compiler): 在编译版本中, 能支持并编译 template属性

    修改webpack.config.js, 指定Vue构建版本 (与entry、output、module属性并列)

    resolve: { alias: { // 指定vue构建版本为编译版本, 当引入Vue依赖时, 会去 node_modules/vue/dist/vue.esm.js 这个文件地址查找 'vue$': 'vue/dist/vue.esm.js' } }

    重新编译 Webpack集成Vue终极使用方案: 使用.vue文件开发

    npm安装 vue-loader(加载vue) 和 vue-template-compiler(vue模板编译)

    npm install vue-loader vue-template-compiler --save-dev

    在webpack.config.js中的module关键字下进行配置

    { test: /\.vue$/, user: { loader: 'vue-loader' } }

    在webpack.config.js中引入Vue加载器插件

    const VueLoaderPlugin = require('vue-loader/lib/plugin') // 从node_modules文件夹中引入vue加载器插件 module.exports = { ..., resolve: { extensions: ['.js', '.css', '.vue'], // 设置导入此文件时, 可以省略后缀名 alias: { 'vue$': 'vue/dist/vue.esm.js' // 指定vue构建版本为编译版本 } }, plugins: [ new VueLoaderPlugin() // 创建vue加载器对象 ] }

    (六) Plugin

    webpack中的插件, 就是对webpack现有功能的各种扩展, 解决 loader 无法实现的功能. 如: 打包优化, 文件压缩等等

    plugin 与 loader 区别:

    loader: 主要用于转换某些类型的模块, 是一个加载, 转换器plugin: 插件, 它是对webpack本身的扩展, 是一个扩展器

    plugin 使用过程

    通过npm安装需要使用的plugins(某些插件已内置)在webpack.config.js中导入plugin插件在webpack.config.js中的 plugins中配置插件

    1. BannerPlugin

    BannerPlugin: webpack自带插件, 为打包的文件bundle.js添加版权声明

    在webpack.config.js中导入plugin插件 和 在plugins中配置插件

    const webpack = require('webpack') module.exports = { ..., plugins: [ new webpack.BannerPlugin('版权最终归 又十七 所有') ] }

    2. html-webpack-plugin

    html-webpack-plugin: 在打包后的文件夹(dist)下, 生成一个index.html文件, 并且将打包的js文件, 自动通过script标签插入到body中

    安装html-webpack-plugin插件

    npm install html-webpack-plugin@3.2.0 --save-dev

    在webpack.config.js中导入plugin插件 和 在plugins中配置插件

    const HtmlWebpackPlugin = requrie('html-webpack-plugin') ... output: { ..., // publicPath: 'dist/' html文件已在dist文件夹中 }, plugins: [ ... , new HtmlWebpackPlugin({ template: 'index.html' // 使用index.html作为模板(index.html已删除打包后的js文件引入) }) ]

    3. uglifyjs-webpack-plugin

    uglifyjs-webpack-plugin: 插件对打包js文件进行压缩(丑化)

    安装uglifyjs-webpack-plugin插件

    npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

    在webpack.config.js中导入plugin插件 和 在plugins中配置插件

    const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') plugins: [ ... , new UglifyjsWebpackPlugin () ]

    (七) Webpack 搭建本地服务器

    webpack提供了一个可选的本地开发务器, 它基于node.js搭建, 内部使用express框架, 可以实现让自动刷新显示我们修改后的结果

    安装webpack-dev-server模块

    npm install webpack-dev-server@2.9.3 --save-dev

    在webpack.config.js中的module关键字下进行配置

    module.exports = { ... , devServer: { contentBase: './dist', // 为哪一个文件夹提供本地服务(默认根文件夹) port: 8080, // 默认使用8080端口 inline: true // 页面实时刷新 } }

    在package.json中的script脚本添加映射命令

    "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "dev": "webpack-dev-server --open" },

    执行终端执行 npm run dev 命令, 会自动打开浏览器页面, 本地服务器搭建完毕

    在此之前我们对webpack.config.js 添加很多配置: entry(入口)、output(出口)、module(loader加载器配置)、pugins(插件)、resolve()、devserver(服务器) 等等. 但有些配置是开发时需要(本地服务器…), 有些配置是编译打包时需要(压缩js文件插件…), 没有做具体的区分

    webpack配置文件分离

    安装webpack-merge依赖

    npm install webpack-merge --save-dev

    拆分配置文件, 配置文件同一放入build文件夹 prod.confg.js

    const webpackMerge = require('webpack-merge') // 导入webpack配置文件合并的依赖 const baseConfig = require('./base.config') // 导入base.config.js 文件依赖 const uglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') // 导入打包压缩js文件插件 // 合并 base.config.js 配置文件 module.exports = webpackMerge(baseConfig, { plugins: [ new uglifyjsWebpackPlugin() ] })

    dev.confg.js

    const webpackMerge = require('webpack-merge') // 导入webpack配置文件合并的依赖 const baseConfig = require('./base.config') // 导入base.config.js 文件依赖 module.exports = webpackMerge(baseConfig, { devServer: { contentBase: './dist', // 为哪一个文件夹提供本地服务(默认根文件夹) port: 9090, // 默认使用8080端口 inline: true // 页面实时刷新 } })

    package.json中scripts脚本命令中指定webpack配置文件

    "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --config ./build/prod.config.js", // 指定prod.config.js 配置文件 "dev": "webpack-dev-server --open --config ./build/dev.config.js" // // 指定dev.config.js 配置文件 }
    Processed: 0.011, SQL: 9