美文网首页
webpack 学习

webpack 学习

作者: Amy_yqh | 来源:发表于2020-06-16 12:02 被阅读0次

1、webpack安装

初始化package.json

npm init -y

安装依赖

cnpm install webpack weback-cli -D

webpack依赖webpack-cli,所以2个都要引入

2、0配置打包

在根目录下新建src文件夹,并新建index.js文件。

index.js
const str = require('./a')
console.log(str)

a.js
module.exports = '一起来学webpack'

开始打包

webpack

在根目录生成一个dist文件夹,里面有打包好的main.js文件

3、webpack基本配置打包

在根目录新建webpack.config.js,我们先配置打包配置的模式、入口、出口

const path = require('path')
module.exports = {
    mode:'development',
    entry: './src/index.js',
    output: {
        filename: "bundle.[hash:8].js",  //输出文件增加hash,防止缓存。如果源文件内容未修改,hash与上一次一致
        path: path.resolve(__dirname,'dist')
    },
}

webpack.config.js人家为默认文件名,支持手动修改。在node-moduls中的webpack-cli/bin/config/config-yargs.js文件中可以查看该名字。

image.png

现在我们把配置文件改为webpack.configmy.js。
有2种打包方式:手打打包、配置脚本打包

1、我们可以任意修改该文件名称,打包时,执行以下命令

webpack --config webpack.configmy.js[修改后的名称]

2、在package.json中配置脚本

"scripts": {
    "build": "webpack --config webpack.configmy.js"
  },

然后在命令行中执行 npm run build

4、webpack打包出来结果分析

image.png

1、我们打开打包后的文件,不难发现,这个文件里面的其实是一个自执行函数。
2、参数modules是一个对象,该对象键为源文件的路径,值为一个函数。
3、自执行函数里面还有一个webpack_require函数,在自执行函数中调用并返回module.exports
4、首先传入的入口文件"index.js",返回值为该函数,该函数又调用webpack_require,传入的引用的a.js文件,最后a.js对应的函数返回module.export。如引用多个,同理。得到的返回结果,在入口文件获取到,并进行操作。

5、webpack-dev-server配置

安装依赖

cnpm install webpack-dev-server -D

在webpack.config.js配置相关参数

devServer: {
      port:3000,                   // 配置指定端口
      progress:true,            // 配置可以看到进度调
      contentBase:'./dist'    // 配置指定目录下的index.html
 }

在package.json 配置脚本

"scripts": {
    "dev": "webpack-dev-server"
  },

注意:
1、打开浏览器时, 默认在根目录寻找index.html ,如果没有index.html则会显示根目录的文件和文件夹。
如有配置,就从配置的目录寻找index.html

6、html-webpack-plugin插件使用

html-webpack-plugin插件用于开发模式下,生成html页面,并把打包后的js文件引用到html模板。

安装依赖及配置

cnpm install html-webpack-plugin -D

webpack.config.js
plugins: [
        new HtmlWebpackPlugin({          // 生成html模板页面
            template: "./src/index.html",       // 模板路径
            filename: "index.html",              // 打包后的文件
            minify: {
                removeAttributeQuotes:true,      // 打包文件html去掉引号(默认为true)
                collapseWhitespace:true          // 缩成一行(默认为true)
            }
        })
    ]

8、查看webpack-dev-server环境下打包生成的文件

[http://localhost:3000/webpack-dev-server](http://localhost:3000/webpack-dev-server)
image.png

9、解析scss、sass、less文件

1、解析scss、sass文件(scss是sass的升级版,用法与扩展名有区别)需要的依赖

cnpm install sass sass-loader -D

配置

          {
              test: /\.sass$/,  
                use: [
                   "style-loader"  // 把css插入head标签
                    'css-loader',   // 识别@import
                    'sass-loader'
                ]
            },
            {
                test: /\.scss$/,   
                use: [
                    "style-loader",
                    'css-loader',   // 识别@import
                    'sass-loader'
                ]
            },

sass的扩展名是sass,scss的扩展名是scss
2、解析less
依赖安装

cnpm install less less-loader

配置

        {
                test: /\.less$/,    //解析css文件
                use: [
                    "style-loader"
                    'css-loader',   // 识别@import
                    'less-loader'
                ]
            }

注意:
1、在.css文件中通过@import引入.scss等文件会无效

10、css合并与样式添加浏览器前缀

安装依赖

cnpm install autoprefixer postcss-loader -D

配置

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
plugins: [
        new MiniCssExtractPlugin({  // 把css处理成一个css文件
            filename:'main.css'
        })
    ],
module: {
        rules: [
            // loader执行顺序:从右到左,从下到上
            {
                test: /\.css$/,    //解析css文件
                use: [
                    MiniCssExtractPlugin.loader, // 把css 打包成一个文件
                    'css-loader',   // 识别@import
                    'postcss-loader',   // css自动增加浏览器前缀

                ]
            },
            {
                test: /\.scss$/,    //解析css文件
                use: [
                    MiniCssExtractPlugin.loader, //合并css为一个文件
                    'css-loader',
                    'postcss-loader', // 添加前缀放在css-loader之前
                    'sass-loader'
                ]
            },
        ]
    }


在根目录新建postcss.config.js

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

要配合在package.json文件配置该文件,否则无效
package.json

"browserslist": [
    "last 2 versions",
    "> 1%",
    "iOS 7",
    "last 3 iOS versions"
  ],

11、压缩css、js

安装依赖

cnpm install optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D

配置

optimization: {
        minimizer: [
            new UglifyJsPlugin({
                cache:true,
                parallel:true,
                sourceMap:true
            }),
            new OptimizeCss()  // css压缩
        ]
},

12、高级js(es6及以上)转为es5 babel-loader

安装插件

cnpm install babel-loader @babel/core @babel/preset-env -D

配置

module: {
        rules: [
            {
                test: /\.js$/,   //解析js(es6转es5等)
                use:{
                    loader: "babel-loader",
                    options: {
                        presets:[
                            '@babel/preset-env'
                        ]
                    }
                },
            },
]}

13、generation语法识别@babel/plugin-transform-runtime

安装插件

cnpm install @babel/plugin-transform-runtime @babel/runtime -D

配置

module: {
        rules: [
            {
                test: /\.js$/,   //解析js(es6转es5等)
               use:{
                    loader: "babel-loader",
                    options: {
                        presets:[
                            '@babel/preset-env'
                        ],
                        plugins:[
                            "@babel/plugin-transform-runtime"
                        ]
                    },
                },
               include: path.resolve(__dirname,'src'),    // 匹配src下的js文件
               exclude: /node_modules/                        // 排除node_modules的文件,否则会找里面的js文件
            },
]}

注意:
一定要配上excelude,否则会去node_modules里面找所有的js文件

该插件主要用于这些语法

function* gen(params) {
    yield 1;
}
console.log(gen().next())

14、重写高级方法@babel/polyfill

安装插件

cnpm install @babel/polyfill(不需要D)

引入

a.js

require('@babel/polyfill')

console.log('aaa'.includes('a'))

查看打包出来的文件,发现在Array.prototype中实现了includes方法。

15、js代码校验 eslint

依赖

cnpm install eslint eslint-loader

配置

  {
                test: /\.js/,  // js代码校验
                use: {
                    loader: "eslint-loader",
                    options: {
                        enforce:'pre',  // js代码校验要在转换之前,增加enforce参
数【pre,post】
                    }
                },
            },

再把官网提供的配置文件引入到根目录

16、全局变量引入问题(变量挂载到window)

安装依赖

cnpm install expose-loader -D

比如说我们引入jquery,其他包需要引入全局的jquery($),

第一种写法:

a.js

import $ from 'expose-loader?$!jquery'

console.log(window.$)

支持 、window.获取
第二种写法:

a.js
import $ from 'jquery'
console.log(window.$)

webpack.config.js
  module: {
        rules: [
            {
                test: require.resolve('jquery'), // 内联loader,把对象暴露出来,挂载到window
                use:'expose-loader?$'
            },
]}

支持¥、window.¥获取
第三种写法

webpack.config.js

plugins: [
        new webpack.ProvidePlugin({
            $:'jquery'
        })
    ],

在每个页面都引入了jquery,支持$获取,不支持window.x

第四种

使用cnd
在index.html

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>

17、图片解析

图片展示方式一般有三种:
1、在js创建imges 展示
2、在css作为background,背景图片使用
3、在html的img标签引入使用

依赖

cnpm install file-loader url-loader html-withimg-loader -D

配置

module: {
        rules: [
            {   // 解析html中的img
                test: /\.html$/,
                use:'html-withimg-loader'
            },
            {
                test: /\.(png|jpg|gif)$/, // 解析js/css中图片的使用
                use:{
                    loader:'url-loader',
                    options: {
                        limit:200*1024, // 小于200k,使用base64,否则显示file-loader真实图片路径
                        outputPath:'img/',  // 图片输出到指定目录下
                        esModule:false  // 用与解决img标签图片中src问题
                    }
                }
            },
]}

使用

1.在js

import global from './Global-Position.png'
let img = new Image()
img.src=global
document.body.appendChild(img)

2、在css
div{
    width: 100px;
    height: 50px;
    background: url("../Global-Position.png");
}

3、在html
<img src="./Global-Position.png" alt="" style="width: 100px;height: 50px"></div>

注意:
1、在img标签引入图片,会有这样的问题

image.png

ERROR in Error: Parse Error: <img src={"default":"389a66a25c539a9fd3524d58c43e2560.png"}> <script type="text/javascript" src="bundle.js?588181ceb9662c845b90"></script></body> </html>
解决方案:
在file-loader 或者url-loader中设置esModule:false

18、打包多入口文件

// 多入口配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    mode:'development',
    entry: {
        home:'./src/firstIndex.js',
        other:'./src/secondIndex.js',
    },
    output: {
        filename: "[name].[hash].js",
        path:path.resolve(__dirname,'dist')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html",
            filename: "home.html",
            chunks: ['home'] // home.html中引入home.js,否则所有的js都会被引入
        }),
        new HtmlWebpackPlugin({
            template: "./src/index.html",
            filename: "other.html",
            chunks: ['other']
        }),
    ]
}

1、entry配置不同的入口文件路径
2、output的filename,使用【name】来区分打包输出的什么文件
3、new多个HtmlWebpackPlugin,生成多个html文件。参数要设置chunks参数需要引入的js文件名字,否则
会把所有的js都引入。

19、source-map 打包映射

  (1)  devtool: "source-map",

代码映射,会单独生成一隔sourcemap文件,出错了会标识当前报错的列和行。js文件很小


image.png
image.png
(2)devtool: "eval-source-map",

不会产生单独的文件,但是可以显示行和列。但是js文件比source-map打包出来的大一些


image.png
image.png
(3) devtool: "cheap-module-source-map",

不会产生列,但是是一个单独的映射文件


image.png
image.png
(4)devtool: "cheap-module-eval-source-map",

不会产生文件,集成在打包后的文件中,不会产生列


image.png
image.png

20、打包watch

webpack.config.js

    watch: true,
    watchOptions: {
        poll: 1000,             //每秒询问一次是否打包
        aggregateTimeout:500,   // 防抖 防止一直输入代码一直打包,页面一直刷新
        ignored: /node_modules/ // 忽略监控文件
    },

监听打包后文件。

21、常用小插件

1、清除插件

cnpm install cleanWebpackPlugin -D


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

2、copy插件

cnpm install copy-webpack-plugin -D

const CopyWebpackPlugin = require('copy-webpack-plugin')

 new CopyWebpackPlugin( [ // 报错??
             { from: 'from', to: './' },
 ])

3、设置版权插件

const webpack = require('webpack')

plugins:[
new webpack.BannerPlugin('make in 2020')
]

打包出来的结果前面会添加版权信息


image.png

22、跨域问题

1、前端解决跨域问题

devServer: {
        proxy:{
            '/api':{ // 请求路径关键字
                target:'http:192.168.1.23:3000',     //代理到的目标
                pathReWrite:{'/api':''}                      // 后台接口可能没有api关键字,要移除掉
            }
        }
    },

2、node后端解决跨域

let middle = require('webpack-dev-middleware')
let config = require('./webpack.config')
let compiler = webpack(config)

app.use(middle(compiler))

3、后端解决跨域

cnpm install cors -D

const cors = require('cors')
app.use(cors())

23、resolve

resolve: {
        modules: [path.resolve('node_modules')],            // 从指定寻找资源
        extensions: ['.js','.css','.json','.vue'],          // 寻找相同名字不同扩展名的文件顺序
        mainFields: ['style','main'],                       // 寻找资源中package.json文件寻找相同名字的文件顺序
        alias: {
            bootstrap:'bootstrap/dist/css/bootstrap.css',    // 资源路径别名
            '@': resolve('src')
        }
    },

24、定义环境变量

 plugins: [
        new webpack.DefinePlugin({    // 设置环境变量,在页面可以直接获取DEV的值
            DEV:JSON.stringify('dev'), // 输出字符串加JSON.stringify,或者多加一个双引号
            FLAG:'true',                    // 输出boolean值
            EXPORESSION:'1+1'
        }),
]

webpack.config.js中配置的环境变量可以在页面中获取

webpack 优化配置

1、noParse 设置无依赖包

noParse:/jquery/,  //没有依赖其他文件的包,设置可以noParse,减少打包时间

2、设置资源寻找范围

module: {
        noParse:/jquery/,  //没有依赖其他文件的包,设置可以noParse,减少打包时间
        rules:[
            {
                test: /\.js$/,
                exclude: /node_modules/,
                include: path.resolve('src'),
                use: {
                    loader: "babel-loader",
                    options: {
                        presets:[
                            '@babel/preset-env'
                        ],
                    }
                }
            }
        ]
    },

我们在页面使用import 引入资源的时候,默认是从node-modules开始寻找该资源,但是如果我们的资源
并不在node-module内,这样会浪费时间,所以我们可以设置一个exclude和include告诉,忽略哪里,从哪里开始寻找

3、设置忽略包

比如项目中引入了moment.js文件,里面的内容包含了所有的语言包,但是并不需要所有。webpack提供了一个IgnorePlugin插件,支持忽略某些内容,减少打包容量,然后再自己手动添加需要的语言包。

new webpack.IgnorePlugin(/\.\/locale/,/moment/)

4、多线程打包

cnpm install happypack -D


const Happypack = require('happypack')
webpack.config.js
 plugins: [
        new Happypack({
            id:'css',
            use:['style-loader','css-loader']
        }),
        new Happypack({
            id:'js',
            use:[{
                loader:'babel-loader',
                options: {
                    presets:['@babel/preset-env']
                }
            }]
        }),
]
 module: {
        rules:[
            {
                test: /\.js$/,
                exclude: /node_modules/,
                include: path.resolve('src'),
                use: 'Happypack/loader?id=js'
            },
            {
                test: /\.css$/,    //解析css文件
                use: 'Happypack/loader?id=css'
            },
            {
                test: /\.scss$/,    //解析css文件
                use: [
                    'css-loader',
                    'postcss-loader',
                    'sass-loader'
                ]
            },
        ]
    },

使用happypack插件创建需要的类型(如css、js),然后在rules中使用对应的happypack,用id来识别。
项目比较小,如果使用多线程打包可能时间返回花得多,因为线程的分配也是需要时间的。

5、抽离公共代码、第三方库

optimization: {
        splitChunks: {
            cacheGroups: {
                common:{// 公共模块
                    chunks: "initial",//初始化的时候进行抽离
                    minSize:0,
                    minChunks:2,// 使用的次数
                },
                vendor:{// 第三方库
                    priority:1,
                    test: /node_modules/,
                    chunks: "initial",
                    minSize:0,
                    minChunks:2
                }
            }
        }
    },

相关文章

网友评论

      本文标题:webpack 学习

      本文链接:https://www.haomeiwen.com/subject/ltklxktx.html