最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • webpack基础知识总结

    正文概述 掘金(超级肥的兔子)   2021-02-12   476

    Webpack

    1.webpack介绍

    1.1.安装

    • webpack核心包
    • webpack-cli命令行工具包
    npm install webpack webpack-cli -D
    

    1.2.入口(entry)

    • 入口起点指示webpack应用使用哪个模块来作为构建内部依赖图的开始。进入入口起点后,webpack会找出有哪些模块和库是入口起点依赖的。
    • 默认值是./src/index.js,我们可以通过webpack config中的entry属性来指定一个/多个不同的入口起点。
    module.exports={
        entry:'./src/index.js'
    }
    

    1.3.出口(output)

    • output属性,告诉webpack在哪里输出它创建的bundle,以及如何命名这些文件。
    • 主要输出文件的默认值是./dist/main.js,其它生成文件默认值放置在./dist文件夹中。

    

    属性描述
    filename文件名path打包后的文件路径publicPath一般设置为'/',打包后插入src中的路径:publicPath+filename
    const path=require('path')
    module.exports={
        output:{
            filename:'main.js',
            path:path.resolve(__dirname,'dist')
        }
    }
    

    1.4.loader

    • webpack只能理解jsjson文件。
    • loaderwebpack能够去处理其它类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加的依赖图中
    module:{
      rules:[
        {test:/\.txt$/,use:'raw-loader'}
      ]
    }
    

    1.5.插件(plugins)

    • loader用于转化某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
    const HtmlWebpackPlugin=require('html-webpack-plugin');
    plugins:[
      new HtmlWebpackPlugin({
        template:'./src/index.html'
      })
    ]
    

    1.6.模式(mode)

    • 前端开发工作中,一般都会有两套环境
    • 开发环境(development),构建结果用于本地开发调试,不进行代码压缩,打印debug信息,包含sourcemap文件
    • 生产环节(production),代码经过压缩处理,运行不打印debug信息,静态文件不包含sourcemap
    1.6.1.环境差异
    • 开发环境(development)
      • 需要生产sourcemap文件
      • 需要打印debug信息
      • 需要live reload或者hot reload的功能
    • 生产环境(production)
      • 可能需要分离css成单独的文件,以便多个页面共享同一个css文件
      • 需要压缩HTML/CSS/JS代码
      • 需要压缩图片
    • 默认值为production
    1.6.2.区分环境
    • --mode:用来设置模块内的process.env.NODE_ENV
    • --env:用来设置webpack配置文件的函数参数
    • cross-env:用来设置node环境的process.env.NODE_ENV
    • DefinePlugin:用来设置模块内的全局变量
    1.6.2.1.命令行配置1
    "scripts": {
        "start":"webpack serve",
        "build":"webpack"
    }
    
    • index.js
    console.log(process.env.NODE_ENV);//production | development
    
    • webpack.config.js
    console.log(process.env.NODE_ENV);//undefined
    
    1.6.2.2.命令行配置2
    "scripts": {
        "start":"webpack serve --mode=development",
        "build":"webpack  --mode=production"
    }
    
    1.6.2.3.命令行配置3
    "scripts": {
        "start":"webpack serve --env=development",
        "build":"webpack  --env=production"
    }
    
    1.6.2.4.mode配置
    module.exports={
      mode:'development'
    }
    
    1.6.2.5.DefinePlugin
    • 设置全局变量(不是window),所有模块都能读取到该变量的值
    • 可以在任意模块内通过process.env.NODE_ENV获取当前的环境变量
    • 无法在node环境(webpack配置文件中)获取当前的环境变量
    new webpack.DefinePlugin({
        PRODUCTION: JSON.stringify(true),
        VERSION: JSON.stringify('1.1.0'),
        BROWSER_SUPPORTS_HTML5: true,
        TWO: '1+1',
    })
    
    • index.js
    //相当于eval()
    console.log('PRODUCTION',PRODUCTION);//true
    console.log("VERSION",VERSION);//1.1.0
    console.log("BROWSER_SUPPORTS_HTML5",BROWSER_SUPPORTS_HTML5);//true
    console.log("TWO",TWO);//2
    
    1.6.2.6.cross-env
    • 只能设置node环境下的变量NODE_ENV
    "scripts": {
      "build": "cross-env NODE_ENV=development webpack"
    }
    
    • webpack.config.js
    console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development
    

    2.开发环境配置

    • devServer会启动一个HTTP开发服务器,把一个文件夹作为静态根目录
    • 为了提高性能,使用的内存文件系统(memory-fs)
    • 默认情况下devServer会读取打包后的路径

    2.1.开发服务器

    2.1.1.安装服务器
    npm install webpack-dev-server -D
    
    2.1.2.参数
    属性描述
    port指定HTTP服务器的端口号compress是否启动压缩 gzipcontentBase静态文件根目录open自动打开浏览器writeToDisk会把打包后的文件写入硬盘一份publicPath:http://locahost/8080/assets/可有通过http://localhost:8080/assets/来访问打包后的静态资源
    devServer: {
        contentBase: path.resolve(__dirname,'static'),
        compress:true,
        port:8080,
        open: true
    }
    
    start:'webpack serve'//5.x
    start:'webpack-dev-server'//4.x
    

    2.2.支持css

    • css-loader用来处理@importurl();
    • style-loadercss插入DOM中;

    2.2.1.安装插件

    npm install style-loader css-loader -D
    
    module:{
      rules:[
        {test:/\.css$/,use:['style-loader','css-loader']}
      ]
    }
    
    body{
      background:red;
    }
    
    @import './bg.css';
    body{
      color:blue;
    }
    
    import './index.css'
    

    2.3.支持less&sass

    2.3.1.安装
    npm install less less-loader -D
    npm install node-sass sass-loader -D
    
    2.3.2.使用
    module:{
        rules:[
            {test:/\.css$/i,use:['style-loader','css-loader']},
            {test:/\.less$/i,use:['style-loader','css-loader','less-loader']},
            {test:/\.scss$/i,use:['style-loader','css-loader','sass-loader']},
        ]
    }
    
    <div id="less-container">less-container</div>
    <div id="sass-container">sass-container</div>
    
    import './less.less';
    import './sass.scss';
    
    @color:oranger;
    #less-container{
        color: @color;
    }
    
    $color:green;
    #sass-container{
        color: $color;
    }
    

    2.4.支持图片

    2.4.1.安装
    • file-loader解决css等文件中引入的图片路径问题
    • url-loader图片小于limit的时候会把图片base54编码,大于limit参数的时候还是使用file-loader进行拷贝
    npm install file-loader url-loader html-loader -D
    
    2.4.2.使用
    { test: /\.html$/, loader: 'html-loader' },
    {
        test: /\.(jpg|png|bmp|gif|svg)$/, use: [{
            loader: 'url-loader',
            options: {
                esModule: false,//默认是true,在代码中取图片是需要.default
                name: '[hash:10].[ext]',//取hash十位作为图片名称,图片ext是扩展名,f0a12b17c9.png
                limit: 8 * 1024//如果文件的体积小于limit,就会转成base64字符串内嵌到HTML中
            }
        }]
    }
    
    <img src="./images/logo.png" >//需要html-loader+url-loader/file-loader
    
    const logo=require('../static/logo.png')
    const img=new Image();
    img.src=logo;
    document.body.appendChild(img);
    
    #img-container{
        width: 400px;
        height: 103px;
        background: url('../static/logo.png');
    }
    

    2.5.JS兼容性处理

    • babel-loader:作用是调用babel/core

    • @babel/core:babel编译的核心包,将ES6转化为ES6语法树,通过babel/preset将ES6转化为ES5语法树,再通过babel/core将ES5语法树转化为ES5代码

    • @babel/preset-env:默认支持语法转换

    • @babel/preset-react:React插件的babel预设

    • @babel/plugin-proposl-decorators:把类和对象装饰器编译成ES5

    • @babel/plugin-proposal-class-proterties:转译静态类属性以及使用属性初始化语法声明的属性

    2.5.1.安装
    npm install babel-loader @babel/core @babel/preset-env @babel/preset-react -D
    npm install @babel/plugin-proposal-decoreators @babel/plugin-proposal-class-properties -D
    
    2.5.2.使用
    {
      test:/\.jsx?$/,
      use:[
        loader:'babel/loader',//调用babel/core
        options:{
        	presets:[
        		'@babel/preset-env',//将ES6转化为ES5语法树
        		'@babel/preset-react'//转化jsx语法
      		],
        	plugins:[//这两个plugins是有顺序的
            ['@babel/plugin-proposal-decorators',{legacy:true}],//转化类和对象
            ['@babel/plugin-proposal-class-properties',{loose:true}]//转化静态类属性
          ]
        }
      ]  
    }
    
    let sum = (a, b) => a + b;
    
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    ReactDOM.render(<h1>hello word</h1>,document.getElementById('root'));
    
    /**
     * 
     * @param {*} target 装饰的目标
     * @param {*} key 装饰的key
     * @param {*} descriptor 装饰的属性描述
     */
    function readonly(target,key,descriptor){
        descriptor.writable=false;
    }
    class Person{
        @readonly PI=3.14;
    }
    
    2.5.3.兼容性处理
    • 最新ES语法:比如,箭头函数
    • 最新ES API:比如,Promise
    • 最新ES 实例方法:比如,String.prototype.includes
    {
      test:/\.jsx?$/,
      use:[{
        loader:'babel-loader',
        options:{
          presets:[
            ['@babel/preset-env':{
             useBuiltIns:'usage',//加载polyfill
             corejs:{version:3},//指定corejs的版本
             target:{//指定要兼容的浏览器
            	chrome:'60',
            	//...
             }
            }]
          ]
        }
      }]
    }
    
    • false,不对polyfill做操作,如果引入@babel/polyfill则无视配置的浏览器,引入所有的polyfill
    • entry,根据配置的浏览器兼容,引入浏览器不兼容的polyfill。需要在入口文件手动添加import @babel/polyfill,会自动根基browserslist替换成浏览器不兼容的所有polyfill;
    • usage,根据配置的浏览器兼容,以及代码中用到的API来进行polyfill,实现按需加载。
    2.5.4.polyfill-service
    • polyfill.io:实现自动加载浏览器所需的 polyfills
    <script src="https://polyfill.io/v3/polyfill.min.js"></script>
    
    2.5.5.babel-runtime
    • babel为了解决全局空间污染的问题,提供了单独的包babel-runtime用以提供编译模块的工具函数
    • 简单说babel-runtime更像是一种按需加载的实现,比如哪里需要使用Promise,只需在哪里的文件头部import Promise from 'babel-runtime/core-js/promise'就可以
    import Promise from 'babel-runtime/core-js/promise';
    
    const p = new Promise((resolve) => {
        resolve('ok');
    });
    
    p.then((data) => console.log(data));
    
    2.5.6.@babel/plugin-transform-runtime
    • 启用插件@babel/plugin-transform-runtime后,babel就会使用babel-runtime下的工具函数
    • @babel/plugin-transform-runtime插件能够将这些工具函数的代码转换成require语句,指向为对babel-runtime的引用
    • @babel/plugin-transform-runtime就是可以在我们使用新API时自动import babel-runtime里面的`polyfill
    plugins: [
      [
        "@babel/plugin-transform-runtime",
        {
          corejs: 2,//当我们使用 ES6 的静态事件或内置对象时自动引入 babel-runtime/core-js
          helpers: true,//移除内联babel helpers并替换使用babel-runtime/helpers 来替换
          regenerator: true,//是否开启generator函数转换成使用regenerator runtime来避免污染全局域
        },
      ],
      ['@babel/plugin-proposal-decorators', { legacy: true }],
      ['@babel/plugin-proposal-class-properties', { loose: true }],
     ],
    

    最佳实践

    2.6.ESLint代码校验

    2.6.1.安装
    npm install eslint eslint-loader babel-eslint -D
    
    2.6.2.使用
    {
      test:/\.jsx?$/,
      loader:'eslint-loader',
      enforce:'pre',//强制指定顺序,统一规则下pre->normal->inline->post
      options:{fix:true},//启动自动修复
      include:path.resolve(__dirname,'src'),//只检测src目录下的  
      exclude:/node_modules/, //排除node_modules  
    }
    
    module.exports = {
        root: true,
        parser: "babel-eslint",
        //指定解析器选项
        parserOptions: {
            sourceType: "module",
            ecmaVersion: 2015
        },
        //指定脚本的运行环境
        env: {
            browser: true,
        },
        // 启用的规则及其各自的错误级别
        rules: {
            "indent": ['error',4],//缩进风格
            "quotes": "off",//引号类型 
            "no-console": "off",//禁止使用console
        }
    }
    
    2.6.3.最佳实践(airbnb)
    npm install eslint-config-airbnb eslint-loader eslint eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks and eslint-plugin-jsx-a11y -D
    
    module.exports = {
        parser:"babel-eslint",
        extends:"airbnb",
        rules:{
            "semi":"error",
            "no-console":"off",
            "linebreak-style":"off",
            "eol-last":"off"
            "indent":["error",4]
        },
        env:{
            "browser":true,
            "node":true
        }
    }
    
    2.6.4.自动修复
    • 安装vscode的eslint插件
    • 配置自动修复参数

    2.7.sourcemap

    devtool: 'hidden-source-map'
    
    2.7.1.配置项
    类型含义
    source-map原始代码,但是编译速度慢eval-source-map原始代码,相对于source-map,会缓存,速度快,evalcheap-module-eval-source-map原始代码(只有行内) 同样道理,但是更高的质量和更低的性能eval生产代码,每个模块都被eval执行,并且存在sourceUrl,带eval的构建模式能cachecheap-source-map转换代码,没有列信息,从loaders生存的sourcemap没有被使用cheap-module-source-map没有行信息,有loader映射cheap-eval-source-map转化代码,没有列信息,每个模块被eval执行,并且sourcemap作为eval的一个dataUrl
    2.7.2.最佳实践
    • 要想速度快,推荐:eval-cheap-source-map

    • 要想调试更友好,推荐:cheap-module-source-map

    • 折中选择:eval-source-map

    • 要想调试友好:sourcemap>cheap-source-map/cheap-module-source-map>hidden-source-map/nosources-sourcemap
    • 要想速度快,优先选择cheap
    • 折中选择hidden-source-map

    2.8.打败第三方类库

    • 直接引入:import
    • 插件引入
    • expose-loader
    • externals
    • Http-webpack-externals-plugin
    2.8.1.直接引入
    import _ from 'lodash';
    
    alert(_.join(['a', 'b', 'c'], '_'));
    
    2.8.2.插件引入
    new webpack.ProvidePlugin({
         _:'lodash'
    })
    
    2.8.3.expose-loader
    • expose-loader:可以把模块添加到全局对象上,在调试的时候比较有用
    • 不需要任何其它插件配合,只需要将下面代码添加到所有loader之前
    npm install expose-loader -D
    
    //=>入口文件
    require('lodash');
    
    //=>webpack.config.js
      module: {
        rules: [
          {
              test: require.resolve('lodash'),
              loader: 'expose-loader',
              options: {
                  exposes: {
                      globalName: '_',
                      override: true,
                  },
              },
          }
        ]
      }
    
    2.8.4.externals
    • index.html
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    
    • index.js
    require('lodash');
    
    • webpack.config.js
    {
      externals:{
        lodash:'_'
      }
    }
    
    2.8.5.html-webpack-externals-plugin
    npm install html-webpack-externals-plugin  -D
    
    const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
    new HtmlWebpackExternalsPlugin({
        externals: [
            {
                module: 'lodash', // 模块名
                entry: "https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.js",
                global: '_', // 全局变量名
            },
        ],
    }),
    

    2.9.mode&env&cross-env

    • webpack --mode=development:改变的是mode的值,代码中可以通过process.env.NODE_ENV取到mode的值;
    • webpack --env=development:改变的是webpack.config.js中导出的函数参数env的值;
    • cross-env NODE_ENV=development webpack serve:改变的是webpack.config.jsprocess.env.NODE_ENV的值;
    2.9.1.--mode
    "start:mode":"webpack serve --mode=development"
    
    console.log(process.env.NODE_ENV);//=>development
    
    2.9.2.--env
    "start:env":"webpack serve --env=development"
    
    module.exports=(env)=>{
      console.log(env.development);
    }
    
    2.9.3.cross-env
    "start:cross":"cross-env NODE_ENV=development webpack serve"
    
    console.log(process.env.NODE_ENV);//=>development
    

    2.10.代码调试

    2.10.1.测试环境调试
    • source-map-dev-tool-plugin:实现了对source map生成,进行更细粒度的控制
      • filenam:定义生成的source map的名称(如果没有值将会变成inlined)
      • append:在原始资源后追加给定值。通常是#sourceMappingURL注释。[url]被替换成source map文件的URL
    • 市面上流行两种形式的文件定义,#@符号开头的,@开头的已经被废弃
    2.10.2.安装
    npm install e
    
    2.10.3.使用
    const FileManagerPlugin=require('file-manager-plugin');
    const webpack=require('webpack');
    module.exports={
      plugins:[
        new webpack.SourceMapDevToolPlugin({
          filename:'[file].map',
          append:'\n//# sourceMappingURL=http://localhost:8081/[url]'
        }),
        new FileManagerPlugin({
          events:{
            onEnd:{
              copy:[{
                source:'./dist/*.map',
                destination:'/Users/dufeihu/Documents/html/zhufeng/复习/day22-webpack/sourcemap'//追加在打包后代码的后面用来找映射sourcemap的地址
              }],
              delete:['./dist/*.map']
            }
          }
        })
      ]
    }
    
    2.10.4.生产环境测试

    2.11.watch

    module.exports = {
      watch: true, // 默认是false,需要手动启动
      watchOptions: { // watch属性
      ignored: /node_modules/, // 不监控的文件/文件夹,支持正则
      aggregateTimeout: 300, // 监听到文件变化后300毫秒再执执行,默认值300ms
      poll: 1000, // 轮询次数,没秒1000次,默认值1000/m
      }
    }
    

    2.12.拷贝静态文件

    2.12.1.安装
    npm install copy-webpack-plugin -D
    
    2.12.2.使用
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    
    new CopyWebpackPlugin({
      patterns: [{
        from: path.resolve(__dirname,'static'),//静态资源目录源地址
        to: path.resolve(__dirname,'dist/static'), //目标地址,相对于output的path目录
      }],
    }),
    

    2.13.清空dist目录

    2.13.1.安装
    npm install clean-webpack-plugin -D
    
    2.13.2.使用
    const CleanWebpackPlugin=require('clean-webpack-plugin');
    module.exports={
      output:{
        filename:'[name][hash:10].js',
        path:path.resolve(__dirname,'dist')
      },
      plugins:[
        new CleanWebpackPlugin({
          cleanOnceBeforeBuildPatterns:['**/*']
        })
      ]
    }
    

    2.14.服务器代理

    2.14.1.不修改路径
    /**
    *	请求地址:http://localhost:8080/api/users
    * 代理地址:http://localhost:3000/api/users
    */
    devServer: {
      proxy: {
        "/api": 'http://localhost:3000'
      }
    }
    
    2.14.2.修改路径
    /**
    *	请求地址:http://localhost:8080/api/users
    * 代理地址:http://localhost:3000/users
    */
    devServer: {
      proxy: {
          "/api": {
           target: 'http://localhost:3000',
           pathRewrite:{"^/api":""}        
          }            
      }
    }
    
    2.14.3.before after
    devServer: {
      before(app){
        // app是一个express()
        app.get('/api/users', function(req, res) { 
           res.json([{ name: 'lisi', age: 20 }]);
        })
      }
    }
    
    2.14.4.webpack-dev-middleware
    • webpack-dev-server的好处是相对简单,直接安装依赖后执行命令即可
    • 使用webpack-dev-middleware的好处是可以在既有express代码基础上快速添加webpack-dev-server的功能,同时利用express来根据需要添加更多的功能

    安装

    npm install webpack-dev-middleware -D
    

    使用

    const express = require('express');
    const app = express();
    const webpack = require('webpack');
    const webpackDevMiddleware = require('webpack-dev-middleware');
    const webpackOptions = require('./webpack.config');
    webpackOptions.mode = 'development';
    const compiler = webpack(webpackOptions);
    app.use(webpackDevMiddleware(compiler, {}));
    app.listen(3000);
    

    3.生产环境

    3.1.提取css

    3.1.1安装
    • mini-css-extract-plugin
    npm install mini-css-extract-plugin -D
    
    3.1.2.使用
    • webpack.config.js
    const MiniCSSExtractPlugin=require('mini-css-extract-plugin');
    
    module.exports={
      output:{
        path:path.resolve(__dirname,'dist'),
        filename:'[name].js',
        publicPath:'/'
      },
      module:{
        rules:[
          //替换掉之前的style-loader,用MiniCSSExtractPlugin.loader
          {
            test:/\.css$/,
            use:[MiniCSSExtractPlugin.loader,'css-loader']
          },
          {
            test:/\.less$/,
            use:[MiniCSSExtractPlugin.loader,'css-loader','less-loader']
          },
          {
            test:/\.scss$/,
            use:[MiniCSSExtractPlugin.loader,'css-loader','sass-loader']
          },
        ]
      },
      plugins:[
        new MiniCSSExtractPlugin({
          filename:'[name].css'
        })
      ]
    }
    

    3.2.指定图片和CSS目录

    3.2.1.webpack.config.js
    module.exports={
      module:{
        rulues:[
          {
            test:/\.(jpg|png|gif|bmp|svg)$/,
            use:[{
              loader:'url-loader',
              options:{
                esModule:false,
                name:'[hash:10].[ext]',
                limit:8*1028,
                outputPath:'images',
                publicPath:'/images'
              }
            }]
          }
        ]
      }
      plugins:[
      	new MiniCSSExtractPlugin({
      		filename:'css/[name].css'
    		})
      ]
    }
    

    3.3.hash,chunkhash和contenthash

    • 文件指纹是打包后输出的文件名和文件后缀
    • hash一般是结合CDN缓存来使用,通过webpack构建之后,生成对应文件名自动带上对应的md5值。如果文件内容改变的话,那么对应文件哈希值也会改变,对应的HTML引用的URL地址也会改变,触发CDN服务器从源服务器上拉取对应数据,进而更新本地缓存。

    指纹转位符

    占位符名称含义
    ext资源后缀名name文件名path文件相对路径folder文件所在的文件夹hash每次webpack构建时生成一个唯一的hash值chunkhash根据chunk生成hash值,来源于同一个chunk,则hash值就一样contenthash根据内容生成hash值,文件内容相同hash值就相同

    3.4.css兼容性

    • 为了浏览器的兼容性,有时候我们必须加入-webkit-ms-o-moz这些前缀
      • Trident内核:主要代表为IE浏览器,前缀为-ms
      • Gecko内核:主要代表为Firefox,前缀为-moz
      • Presto内核:主要代表为Opera,前缀为-o
      • Webkit内核:主要代表为Chrome和Safari,前缀为-webkit
    • 伪元素::placeholder可以选择一个表单元素的占位文本,它允许开发者和设计师自定义占位文本的样式
    3.4.1.安装
    • postcss-loader:可以使用PostCSS处理CSS
    • postcss-preset-env:把现代的CSS转换成大多数浏览器能理解的
    • PostCSS Preset Env已经包含了autoprefixerbrowsers选项
    npm install postcss-loader postcss-preset-env -D
    
    3.4.2.postcss.config.js
    const postcssPresetEnv = require('postcss-preset-env');
    
    module.exports = {
        plugins: [postcssPresetEnv()],
    };
    
    3.4.3.webpack.config.js
    module.exports={
      module:{
        rules:[
          {
            test:/\.css$/,
          use:[MiniCSSExtractPlugin.loader,'css-loader','postcss-loader']
          },
          {
            test:/\.less$/,
          use:[MiniCSSExtractPlugin.loader,'css-loader','postcss-loader','less-loader']
          },
          {
            test:/\.scss$/,
          use:[MiniCSSExtractPlugin.loader,'css-loader','postcss-loader','sass-loader']
          },
        ]
      }
    }
    
    3.4.4.index.css
    ::placeholder{
        color: red;
    }
    
    3.4.5.index.html
    <input placeholder="请输入"/>
    
    3.4.6.编译后结果
    :-moz-placeholder{
        color: red;
    }
    :-ms-input-placeholder{
        color: red;
    }
    ::placeholder{
        color: red;
    }
    

    3.5.压缩JS,CSS和HTML

    • optimize-css-assets-webpack-plugin:是一个优化和压缩css资源的插件
    • terser-webpack-plugin:是一个优化和压缩JS资源的插件
    3.5.1.安装
    npm install optimize-css-assets-webpack-plugin terser-webpack-plugin -D
    
    3.5.2.webpack.config.js
    const OptimizeCssAssetsWebpackPlugin=require('optimize-css-assets-webpack-plugin');
    const TerserWebpackPlugin=require('terser-webpack-plugin');
    const HtmlWebpackPlugin=require('html-webpack-plugin');
    
    module.exports={
      optimization:{
        minimize:true,
        minimizer:[
          new TerserPlugin()
        ]
      },
      plugins:[
        new HtmlWebpackPlugin({
          template:'./src/index.html',
          minify:{
            collapseWhitespace:true,
            reomoveComments:true
          }
        }),
        new OptimizeCssAssetWebpackPlugin()
      ]
    }
    

    3.6.px自动转成rem

    • lib-flexible+rem,实现移动端自适应
    • px2rem-loader自动将px转换为rem
    • 页面渲染时计算根元素的font-size
    3.6.1.安装
    npm install px2rem-loader lib-flexible -D
    
    3.6.2.index.html
    <script>
    	const docEle=document.documentElement;
      function setRemUnit(){
        docEle.style.fontSize=docEle.clientWith/10+'px';
      }
      setRemUnit();
      window.addEventListener('resize',setRemUnit)
    </script>
    
    3.6.3.reset.css
    *{
      margin:0;
      padding:0;
    }
    #root{
      width:750px;
      height:750px;
      border:1px solid red;
      box-sizing:border-box;
    }
    
    3.6.4.webpack.config.js
    module.exports={
      module:{
        rules:[
          {
            test:/\.css$/,
            use:[{
              MiniCssExtractPlugin.loader,
              'css-loader',
              'postcss-loader',
              {
              	loader:'px2rem-loader',
              	options:{
              		remUnit:75,
              		remPrecesion:8
            		}
            	}
            }]
          }
        ]
      }
    }
    

    3.7.多入口打包

    const fs = require('fs');
    
    const pagesRoot = path.resolve(__dirname, 'src', 'page');
    const dirs = fs.readdirSync('./src/page');
    const htmlWebpackPlugins = [];
    const entry = dirs.reduce((memo, current) => {
        const name = path.basename(current, '.js');
        // eslint-disable-next-line no-param-reassign
        memo[name] = path.join(pagesRoot, current);
        htmlWebpackPlugins.push(new HtmlWebpackPlugin({
            template: path.resolve(__dirname, './src/index.html'),
            filename: `${name}.html`,
            chunks: [`${name}`],
            minify: {
                collapseInlineTagWhitespace: true,
                removeComments: true,
            },
        }));
        return memo;
    }, {});
    
    module.exports{
      entry,
      plugins:[
        ...htmlWebpackPlugins
      ]  
    }
    

    3.8.webpack-merge

    3.8.1.安装
    npm install webpack-merge -D
    
    3.8.2.webpack.base.js
    module.exports={
      entry:'./src/index.js',
      output:{
        filename:'[name][hash:10].js',
        path:path.resolve(__dirnanem,'dist')
      }
    }
    
    3.8.3.webpack.dev.js
    const merge=require('webpack-merge');
    const base=require('./webpack.base.js')
    module.exports=merge(base,{
      mode:'development'
    })
    
    3.8.4.webpack.prod.js
    const merge=require('webpack-merge');
    const base=require('./webpack.base.js')
    module.exports=merge(base,{
      mode:'production'
    })
    

    3.9.env

    • dotenv
    3.9.1.安装
    npm install dotenv -D
    
    3.9.2..env
    NODE_ENV=development
    
    3.9.3.webpack.config.js
    require('dotenv').config();
    console.log('process.env.NODE_ENV',process.env.NODE_ENV);//=>development
    

    起源地下载网 » webpack基础知识总结

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元