从零开始学webpack(v4.0)

1.什么是webpack?

webpack是一个现代JavaScript应用程序的静态模块打包工具。当webpack处理应用程序时,它会在内部构建一个依赖图(dependency graph),此依赖图会映射项目所需的每个模块,并生成一个或多个bundle包!webpack本身是基于node.js开发的!

官网:https://webpack.docschina.org/

2.为啥要使用webpack?

  • 代码转换:TypeScript编译成JavaScript、LESS/SCSS编译成CSS、ES6/7编译为ES5、虚拟DOM编译为真实的DOM等等…

  • 文件优化:压缩JS、CSS、HTML代码,压缩合并图片,图片BASE64等

  • 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码等

  • 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件

  • 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器

  • 代码校验:Eslint代码规范校验和检测、单元测试等

  • 自动发布:自动构建出线上发布代码并传输给发布系统

  • ……

扩展:模块化的发展史:

  • 单例设计模式(Singleton Pattern)

  • AMD (Asynchronous Module Definition 异步模块定义)

  • CMD (Common Module Definition 通用模块定义)

  • CommonJS(一般应用于服务器开发,例如:Node.js)

  • ES6 Module (ESM : JS官方标准模块定义方式) https://es6.ruanyifeng.com/#docs/module

  • ……

3.webpack的基础操作

安装

// 为防止全局安装webpack导致版本冲突,真实项目中以本地安装为主 
$ npm init -y
$ npm install webpack webpack-cli --save-dev
OR
$ yarn add webpack webpack-cli -D

零配置使用

/*
 * 默认会打包SRC目录中的JS文件(入口默认index.js)
 * 打包完成的目录默认是DIST/MAIN.JS
 * webpack默认支持CommonJS和ES6 Module的模块规范,依此进行依赖打包
 */
$ npx webpack

自定义基础配置

webpack.config.js OR webpackfile.js

let path = require('path');
module.exports = {
    //=>打包模式  开发环境development  生产环境production
    mode: 'production',
    //=>入口
    entry: './src/index.js',
    //=>输出
    output: {
        //=>输出文件的文件名
        filename: 'bundle.js',
        //=>输出目录的"绝对路径"
        path: path.resolve(__dirname, 'dist')
    }
}

自定义配置文件名

  • $ npx webpack –config webpack.config.development.js

  • 可在package.json中配置可执行的脚本命令(区分开发环境)

"scripts": {
    "serve": "webpack --config webpack.config.development.js",
    "build": "webpack --config webpack.config.production.js"
},

html-webpack-plugin

https://www.webpackjs.com/plugins/html-webpack-plugin/
$ npm i html-webpack-plugin –save-dev`

let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    ...,
    //=>在webpack中使用插件
    plugins: [
        new HtmlWebpackPlugin({
            //=>指定自己的模板
            template: './src/index.html',
            //=>输出的文件名
            filename: 'index.html',
            //=>给引入的文件设置HASH戳(清除缓存的),也可以在output中设置 filename: 'bundle.[hash].js' 来生成不同的文件
            hash: true,
            //=>控制是否以及以何种方式最小化输出 
            //=>https://github.com/kangax/html-minifier
            minify: {
                collapseWhitespace: true,
                removeComments: true,
                removeAttributeQuotes: true,
                removeEmptyAttributes: true
            }
        })
    ]
}

clean-webpack-plugin

每一次打包之前,清除之前打包的内容
$ npm install clean-webpack-plugin –sav-dev

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports={
    plugins:[
        new CleanWebpackPlugin()
    ]
};

webpack-dev-server

https://webpack.js.org/configuration/dev-server/
$ npm install webpack-dev-server –save-dev

/* webpack.config.js */
//=>配置DEV-SERVER  **内存中编译打包**
devServer: {
    //=>端口
    port: 3000,
    //=>开启GZIP压缩
    compress:true,
    //=>显示编译进度
    progress: true,
    //=>指定访问资源目录
    contentBase: path.resolve(__dirname, "dist"),
    //=>自动打开浏览器
    open: true,
    //=>开启热更新
    hot:true,
    //=>请求代理
    proxy:{
       "/":{
          target:"http://localhost:8888", 
          secure: false, //若为true则表示是https,false是http
          changeOrigin: true //把请求头当中的host值改成服务器地址
       } 
    }
}

/* package.json */
"scripts": {
    "serve": "webpack-dev-server",
    "build": "webpack"
}

4.多入口、多出口

const htmlPlugins = ['index', 'login'].map(chunk => {
    return new HtmlWebpackPlugin({
        template: `./${chunk}.html`,
        filename: `${chunk}.html`,
        hash: true,
        chunks:[chunk,'jquery'],
        minify: {
           collapseWhitespace: true,
           removeComments: true,
           removeAttributeQuotes: true,
           removeEmptyAttributes: true
       }
   });
});

module.exports={
    entry: {
        index: "./src/index.js",
        login: "./src/login.js",
        jquery:"./src/jquery.js"
    },
    output: {
        filename: "[name].[hash].js",
        path: path.resolve(__dirname, "dist")
    },
    plugins:[
        ...htmlPlugins
    ]
};

5.webpack中的加载器loader:处理样式的

$ npm install css-loader style-loader less less-loader autoprefixer postcss-loader –save-dev

module.exports = {
    //=>配置模块加载器LOADER
    module: {
        //=>模块规则:使用加载器(默认从右向左执行,从下向上)
        rules: [{
            test: /\.(css|less)$/, //=>基于正则匹配哪些模块需要处理
            use: [
                "style-loader", //=>把CSS插入到HEAD中
                "css-loader", //=>编译解析@import/URL()这种语法
                "postcss-loader", //=>设置前缀
                {
                    loader: "less-loader",
                    options: {
                        //=>加载器额外的配置
                    }
                }
            ]
        }]
    }
}

postcss.config.js

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

package.json

// https://github.com/browserslist/browserslist
"browserslist": [
    "> 1%",
    "last 2 versions"
]

6.mini-css-extract-plugin 抽离CSS内容

https://www.npmjs.com/package/mini-css-extract-plugin
$ npm install mini-css-extract-plugin –save-dev

const MiniCssExtractPlugin=require('mini-css-extract-plugin');
module.exports = {
    plugins: [
        //=>使用插件
        new MiniCssExtractPlugin({
            //=>设置编译后的文件名字
            filename: 'main.[hash].css'
        })
    ],
    module: {
        rules: [{
            test: /\.(css|less)$/,
            use: [
                // "style-loader",
                //=>使用插件中的LOADER代替STYLE方式
                MiniCssExtractPlugin.loader,
                "css-loader",
                "postcss-loader",
                "less-loader"
            ]
        }]
    }
}

7.设置优化项压缩CSS/JS

$ npm install optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin terser-webpack-plugin –save-dev

const UglifyjsWebpackPlugin=require('uglifyjs-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin= require('optimize-css-assets-webpack-plugin');

module.exports = {
    //=>设置优化项
    optimization: {
        //=>设置压缩方式
        minimizer: [
            //=>压缩CSS(但是必须指定JS的压缩方式)
            new OptimizeCssAssetsWebpackPlugin(),
            //=>压缩JS
            //new UglifyjsWebpackPlugin({
                //cache: true, //=>是否使用缓存
                //parallel: true, //=>是否是并发编译
                //sourceMap: true, //=>启动源码映射(方便调试)
            //}),
            new TerserPlugin()
        ]
    }
};

8.webpack中图片的处理

$ npm install file-loader url-loader html-withimg-loader –save-dev

module.exports = {
    module: {
        //=>模块规则:使用加载器(默认从右向左执行)
        rules: [{
            test: /\.(png|jpe?g|gif)$/i,
            use: [{
                //=>把指定大小内的图片BASE64
                //=>不在指定范围的采用file-loader进行处理
                loader: 'url-loader',
                options: {
                    limit: 200 * 1024,
                    outputPath:'/images',
                    //name:'[name].[ext]'
                }
            }],
            include: path.resolve(__dirname, 'src'),
            exclude: /node_modules/
        }, {
           test:/\.(svg|eot|ttf|woff|woff2)$/i,
           use:"file-loader"
        }, {
            test: /\.html$/,
            use: ['html-withimg-loader']
        }]
    }
}

9.基于babel实现ES6的转换和ESLint语法检测

https://babeljs.io/
https://eslint.org/
$ npm install babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime –save-dev
$ npm insall @babel/runtime @babel/polyfill
$ npm install eslint eslint-loader –save-dev

module.exports = {
    module: {
        rules: [{
            test: /\.js$/,
            use: [{
                loader: 'babel-loader',
                options: {
                    //=>转换的语法预设(ES6->ES5)
                    presets: [
                        "@babel/preset-env"
                    ],
                    //=>基于插件处理ES6/ES7中CLASS的特殊语法
                    plugins: [
                        ["@babel/plugin-proposal-decorators", {
                            "legacy": true
                        }],
                        ["@babel/plugin-proposal-class-properties", {
                            "loose": true
                        }],
                        "@babel/plugin-transform-runtime"
                    ]
                }
            }], //=>, "eslint-loader"
            //=>设置编译时忽略的文件和指定编译目录
            include: path.resolve(__dirname, 'src'),
            exclude: /node_modules/
        }]
    }
}

类的装饰器

@log
class A{
    a=1;
}
function log(target){}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值