webpack学习笔记

栏目: 编程语言 · 发布时间: 5年前

内容简介:面试常见考点起步

简介

webpack 可以做的事

  • 代码转换
  • 文件优化
  • 代码分割
  • 模块合并
  • 自动刷新
  • 代码校验
  • 自动发布

面试常见考点

  • webpack 常见配置
  • webpack 高级配置
  • ast 抽象语法树
  • webpack 中的 Tapable
  • 掌握 webpack 流程,手写 webpack
  • 手写 webpack 中常见的 loader
  • 手写 webpack 中常见的 plugin

webpack 基础配置

起步

  • 创建 src ---> index.js
  • npx webpack
  • 基础配置
//webpack是node写出来的,所以需要node的写法

let path = require('path')   //核心模块

module.exports = {
    mode: 'development',                    //默认两种:production development
    entry: './src/index.js',                //入口
    output: {                               //出口
        filename: 'bundle.js', //打包后的文件名
        path: path.resolve(__dirname, 'dist'), //resolve把相对路径解析成绝对路径,__dirname意思是在当前目录建立一个,路径必须是一个绝对路径
    }
}

script 脚本

npx webpack --config webpack.config.js
"scripts": {
    "build": "webpack"
  }

//npm run build
  • 传参 npx webpack -- --config webpack.config.js

Html 插件

npx webpack-dev-server

express

htmlWebpackPlugin

  • 将打包后的 js 文件插入 html 文件,并放到 build 目录下
let htmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    devServer: {                                //开发服务器的配置
        port: 3000,                             //设置端口号
        progress: true,                         //进度条
        contentBase: '/.build',                  //指定静态目录
        compress: true
    },
    output: {
        filename: 'bundle.[hash:8].js',         //文件名
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [                                  //数组 放着所有的webpack插件
        new htmlWebpackPlugin({
            template: './src/index.html',       //模板
            filename: 'index.html',             //打包后的文件名
            minify: {                           //打包后的html也压缩
                removeAttributeQuotes: true,    //删除属性的双引号
                collapseWhitespace: true,       //折叠空行
            },
            hash: true                          //html文件加上哈希戳
        })
    ]
}

css 配置

loader : Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。

Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果

css 配置

  • css-loader 解析 @import 这种语法
  • style-loadercss 插入到 head 的标签中
  • loader 的特点:希望单一
  • loader 的用法:字符串只用一个 loader ,多个 loader 需要 []
  • loader 的顺序:默认是从右向左执行       从下往上

优先级

{
    loader: 'style-loader',
    options: {
        insertAt: 'top'    //确保优先级
    }
}

处理 lesssassstylus

yarn add less less-loader
yarn add node-sass sass-loader
yarn add stylus stylus-loader
module.exports = {
    module: {                                       //模块
        rules: [                                    //规则 
                                        //loader的特点:希望单一
            //{ test: /\.css$/, use: ['style-loader', 'css-loader'] }   //第一种:写法
                                        //loader还可以写成对象方式
            {
                                        //处理less文件
                test: /\.css$/,
                use: [{
                        loader: 'style-loader',
                        options: {
                            insertAt: 'top'    //确保优先级
                        }
                    },
                    'css-loader',              //@import  解析路径
                    'less-loader'              //把less ---->css  
                ]
            }
        ]
    }
}

抽离 CSS 的插件

  • 默认打包后只能插入 <style> 标签内,我们希望抽离成 <link> 形式
  • 通过 mini-css-extract-plugin 这个插件
  • yarn add mini-css-extract-plugin -D
  • 插件都是类 插件的使用顺序没有先后
let MiniCssExtractPlugin = require('mini-css-extract-plugin')

//配置plugin
plugins: [
        new MiniCssExtractPlugin({
            filename: 'main.css',
        })
    ],

//配置module    
module: {
        rules: [{
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            }
        ]
    }

自动添加前缀

autoprefixer
postcss-loader
yarn add postcss-loader autoprefixer
//配置module
//先处理post-css再处理css
module: {
        rules: [{
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader','postcss-loader']       //加上post-css
            },
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
            }
        ]
    }
//创建postcss.config.js文件并配置

module.exports = {
    plugins: [require('autoprefixer')]
}

压缩 css (同时保证 js 的压缩)

optimize-css-assets-webpack-plugin
yarn add optmize - css - assets - webpack - plugin - D
uglifyjs-webpack-plugin
let path = require('path')
let htmlWebpackPlugin = require('html-webpack-plugin')
let MiniCssExtractPlugin = require('mini-css-extract-plugin')
let OptimizeCss = require('optimize-css-assets-webpack-plugin')
let UglifyJsPlugin = require('uglifyjs-webpakc-plugin')

module.exports = {
    Optimization: { //***优化项,用了这个插件之后就必须用一下Uglifyjs压缩js
        minimizer: [
            new UglifyJsPlugin({
                cache: true, //是否用缓存
                parallel: true, //是否并行打包
                sourceMap: true
            }),
            new OptimizeCss()
        ]
    },
    devServer: {
        port: 3000,
        progress: true,
        contentBase: '/.build'
    },
    mode: 'development',
    entry: './src/index.js',
    output: {
        filename: 'bundle.[hash:8].js',
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [
        new htmlWebpackPlugin({
            template: './src/index.html',
            filename: 'index.html',
            minify: {
                removeAttributeQuotes: true,
                collapseWhitespace: true,
            },
            hash: true
        }),
        new MiniCssExtractPlugin({
            filename: 'main.css'
        })
    ],
    module: {
        rules: [
            //{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader, //***创建link标签,引用
                    'css-loader',
                    'less-loader',
                    'postcss-loader'

                ]
            }
        ]
    }
}

JS 配置

转化es6语法

babel

yarn add babel-loader @babel/core @babel/preset-env -D
module
module: {
        rules: [{
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {          //用babel-loader es6---->es5
                        presets: [
                            '@babel/preset-env'
                        ]
                    }
                }
            }
        ]
    }

配置提案里支持的语法

class A{
    a = 1;
}
  • yarn add @babel/plugin-proposal-class-properties -D
{
    test: /\.js$/,
    use: {
        loader: 'babel-loader',
        options: {
            presets: [
                '@babel/preset-env'
            ],
            plugins: [
                '@babel/plugin-proposal-class-properties'
            ]
        }
    }
}

支持装饰器语法

function log(target) {
    console.log(target, '23')
}

log(A)
  • yarn add @babel/plugin-proposal-decorators -D

配置 module

module: {
        rules: [{
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: { //用babel-loader es6---->es5
                        presets: [
                            '@babel/preset-env'
                        ],
                        plugins: [
                            ['@babel/plugin-proposal-class-properties'],
                            ['@babel/plugin-proposal-decorators',{"legacy":true}],
                            ['@babel/plugin-transform-runtime']
                        ]
                    }
                }
            }
        ]
    }

处理 JS 语法及校验

function *gen(params){
        yield 1;     
    }
    console.log(gen().next());  //内置API
    
// Uncaught ReferenceError: regeneratorRuntime is not defined

babel-runtime

yarn add @babel/plugin-transform-runtime -D
yarn add @babel/runtime
module: {
        rules: [{
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: { //用babel-loader es6---->es5
                        presets: [
                            '@babel/preset-env'
                        ],
                        plugins: [
                            ['@babel/plugin-proposal-class-properties'], ['@babel/plugin-proposal-decorators',{"legacy":true}],
                            ['@babel/plugin-transform-runtime']
                        ]
                    }
                },
                include:path.resolve(__dirname,'src'),  //包括查找范围
                exclude:/node_module/                   //排除查找范围
            }
        ]
    }

@babel/polyfill

'aaa'.include('a')  //ES7语法

//实例上的方法默认都不会解析
  • yarn add @babel/polyfill
//a.js
require('@babel/polyfill')
'aaa'.include('a')

eslint

  • yarn add eslint eslint-loader
module: {
        rules: [     //loader默认从右向左执行 从下到上,写的太多容易乱,写到一起删除不方便
            {
                test:\.js$/,
                use:{
                    loader:'eslint-loader',
                    options:{
                        enforce:'pre'   //previous -> normal-> post 顺序执行
                    }
                }
            }
            /*...*/
        ]
}
  • 选择好配置,下载 .eslintrc.jsonconfiguration

全局变量引入问题

yarn add jquery
import $ form 'jqurey'
console.log($) 
console.log(window.$) //undefined,并不会挂载到window上

如何将变量暴露给 window ?

expose-loader (内联 loader )

  • yarn add expose-loader
import $ from 'expose-loader?$!jquery'   //将jquery作为$暴露给全局
  • 也可以在 webpack.config.js 中配
module: {
        rules: [{
                test: require.resolve('jquery'),
                use: 'expose-loader?$!jquery'
                }
        ]
    }
  • 在每个模块中注入 $ 对象
//webpack.config.js
let Webpack = require('webpack')
 new Webpack.ProvidePlugin({
            //再每个模块中都注入$符
    jqurey: '$'
})
//index.js
console.log($)   //只是在每个模块中都注入一个`$`
//此时window.$   //undefined

cdn 外部路径引入

<script src="https://cdn.bootcss.com/jquery/3.3.1/core.js"></script>
//如果此时js也引入jquery会导致重复
import $ form jquery
externals: {
        jquery: 'jQuery'   //告诉webpack从外部引入,并不需要打包,忽略
    },

总结

expose-loader
providePlugin

loader 类型

  • pre              前面执行的 loader
  • normal         普通的 loader
  • liader        内联 loader
  • post            后置 loader

图片处理

图片引入方式

  • js 中创建图片来引入
let image = new Image()
image.src = './logo.png'
document.body.appendChild(image) //打包完,其实就是一个普通的字符串,并没有真正的引入图片

file-loader

yarn add file-loader
build
//webpack.config.js

module: {
        rules: [{
                test: /\.(png|jpg|gif)$/,
                use: 'file-loader'
            }
        ]
}
//index.js

import logo from './logo.png' //把图片引入,生成一个哈希戳的logo,返回的结果是一个新的图片

console.log(logo)

let image = new Image();
image.src = logo;
document.body.appendChild(image)
  • css 中引入 background('url')
  • <img src="" alt="">

打包文件分类

打包多页应用

配置 source-map


以上所述就是小编给大家介绍的《webpack学习笔记》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

企业应用架构模式

企业应用架构模式

Martin Fowler / 王怀民、周斌 / 机械工业出版社 / 2010-4 / 59.00元

《企业应用架构模式》作者是当今面向对象软件开发的权威,他在一组专家级合作者的帮助下,将40多种经常出现的解决方案转化成模式,最终写成这本能够应用于任何一种企业应用平台的、关于解决方案的、不可或缺的手册。《企业应用架构模式》获得了2003年度美国软件开发杂志图书类的生产效率奖和读者选择奖。《企业应用架构模式》分为两大部分。第一部分是关于如何开发企业应用的简单介绍。第二部分是《企业应用架构模式》的主体......一起来看看 《企业应用架构模式》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码