Webpack 基础流程

安装 webpack 和 webpack cli

yarn add webpack webpack-cli -D

创建webpack.config.dev.js

开发版本下的配置文件

const path = require('path')

module.exports={
    //模式(development,production)
    mode:'development',
    
    //
    devtool:'source-map'

    //入口文件,如果不配置entry项,则默认在src目录下找index.js,
    entry: {
        index:'./src/js/index.js',
        //detail:'./src/js/detail.js'  如果是多页面情况,则可以直接在entry中写别的页面
    },
    
    //将两个文件打包到一个下
    //entry:[path.resolve(__dirname,'../app.js'),path.resolve(__dirname,'../component/Heade.js')] 

    //出口文件,路径不可为相对路径,如果不设置output项,则默认导出到根目录的dist/main.js文件
    output:{
        //路径
        path:path.resolve(__dirname,'./dist'),
        //文件名,这里可添加6位哈希后缀
        filename:'index-[hash:6].js'
        
        //当配置了多页面的时候,这里就需要起别名了,这里就会根据入口文件名打包成两个文件。
        filename:'[name].js'
    }
}

文件后缀hash生成是根据文件的内容进行编码的,内容不变化则hash值不变化

打包路径设置

module.export={
    ...
    
    entry: {
        'script/index':path.resolve(__dirname,'./app.js')
        //在入口文件名处可以写路径信息,也会添加到相应文件内
    },
    
    output: {
        //在文件名前面可以添加路径,打包后会放到指定的路径下
        filename: 'script/[name]-[hash:6].js'
    },
}

安装 HtmlWebpackPlugin

将页面模板页面和js文件进行整合

...
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    ...
    plugins: [//js与html模板匹配
        new HtmlWebpackPlugin({//实例化
            title: '没啥意思的小网页',
            //设置打开的标签页名称 title,模板页面设置<title><%= htmlWebpackPlugin.options.title %></title>

            template: './src/views/index.ejs',
            //模板文件路径

            //自动存储到  output配置的目录
            filename: 'index.html',
            //默认为index.html,如果更改可从服务端修改首页名称,

            // chunks: ['index']
            //指定入口的js文件,仅添加所需的模块,不将其他与本页无关的模块加载进来
        }),
    ]
}

安装 webpack-dev-server

webpack-dev-server为你提供了一个简单的web服务器,并且能够实时重新加载(live reloading)。文件时保存再内存中的,打开速度更加迅速。

官网:https://www.webpackjs.com/guides/development/#%E4%BD%BF%E7%94%A8-webpack-dev-server

yarn add webpack-dev-server -D

安装后可以在webpack.config.dev.js中配置 devServer项,可以设置浏览器打开和端口号

module.exports = {
    ...
    devServer: {
        port: 9000,//端口号
        open: true,//打开浏览器
        contentBase: './dist',//serve运行的根目录
        compress:true//是否压缩
    }
}

配置完成后需要在package.json中配置下面这,即可通过 yarn dev来启动

"dev": "webpack-dev-server --config webpack.config.dev.js"

sass-loader的使用

把浏览器不识别的内容做转换,loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。

创建scss文件:common.scss

$base: blue;

body{
    background:$base;
}

在入口文件index.js中引入

import '../style/common.scss'

class Index{
    constructor(){
        console.log('webpack.js')
    }
}

new Index()

在yarn dev 的时候webpack并不会识别scss的文件,这个时候就需要loader来帮助webpack来识别内容并且编译

在引入scss的时候需要安装 node-sass sass-loader

 yarn add node-sass sass-loader 

在使用sass-loader的时候需要安装另外两个依赖:css-loader,style-loader

module.exports = {
    ...
    module: {
        rules: [
            {
                test: /\.s[ac]ss$/,//选择出需要转换的文件
                use: [

                    //将JS字符串生成为style节点,会在页面生成style样式
                    'style-loader',

                    //将css转换为common.js模块
                    'css-loader',

                    //把.sass .scss转为.css
                    'sass-loader'

                ]
            }
        ]
    }
}

这种形式的写法会导致样式文件直接插入到页面的head标签内部的style标签内,有时候我们还需要引入单独的css文件,这时候就需要MiniCssExtractPlugin。

MiniCssExtractPlugin

安装

yarn add mini-css-extract-plugin -D

用法:首先在入口文件引入样式文件,再由该插件独立出来

...
const miniCssExtractPlugin = require(mini-css-extract-plugin)
module.exports = {
    ...
    plugins:[
        ...
        new miniCssExtractPlugin({
            filename:'[name]-[hash:6].css'
            //设置了css文件名字和入口entry文件名一致,并添加6位哈希
        })
    ],
    module: {
        rules: [
            {
                test: /\.s[ac]ss$/,//选择出需要转换的文件
                use: [
                
                    miniCssExtractPlugin.loader,

                    //这里不需要渲染为style标签的形势了,所以可以不走style-loader
                    //'style-loader',

                    //将css转换为common.js模块
                    'css-loader',

                    //把.sass .scss转为.css
                    'sass-loader'

                ]
            }
        ]
    }
}

因为我们在entry入口处配置了路径:

entry: {
        'script/index':path.resolve(__dirname,'./app.js')
    },

当我们想要将css文件导报到指定路径下时可以在miniCssExtractPlugin中配置moduleFilename

new miniCssExtractPlugin({
    // filename: '[name]-[hash:6].css',
    moduleFilename: ({ name }) => `${name.replace('script', 'style')}-[hash:6].css`,
    //将原本的script替换为style路径,并为css文件添加hash后缀
})

生产环境的配置

将一些生产条件下不需要的内容去掉,并且在package.json中定义

"build":"webpack --config webpack.config.pro.js" 

devTool

module.exports={
    ...
    devtool:'inline-source-map'
    //代码调试,可以看到源代码
}

babel 和垫片@babel/polyfill 的使用

babel的初次使用

当我们引入高标准代码后,浏览器可能不识别类似箭头函数,promise,let等语法,这时候就需要babel语法转换器

我们需要使用babel-loader时需要按照的依赖

npm install -D babel-loader @babel/core @babel/preset-env
yarn add babel-loader @babel/core @babel/preset-env --dev

创建一个js文件,并且在入口文件引入import './app.js'

//app.js

const fuc=()=>{
    console.log('箭头函数')
}

export default fuc

然后需要在config中配置一下module

module:{
    {
        test:/\.js$/,
        use:{
            loader:'babel-loader',
            options:{
                //插件集合
                presets:['@babel/preset-env']
            }
        }
    }
}

通过yarn build 打包后的js文件内就不是原封不动的js,而是编译完成的浏览器可识别的代码

__webpack_require__.r(__webpack_exports__);
var fuc = function fuc() {
  console.log('箭头函数');
};
垫片

安装

yarn add @babel/polyfill --dev

方法一:简单粗暴,在入口文件引入,即可将高阶代码转换为低版本的

import @babel/polyfill

这样会把所有的方法载入,文件内容会很大,所以垫片的形式不会按需载入,且会污染全局环境

方法二:在配置文件的entry导入

entry: {
        index:['@babel/polyfill',path.resolve(__dirname,'./js/index')]
    },

方法三:设置presets

module:{
    {
        test:/\.js$/,
        use:{
            loader:'babel-loader',
            options:{
                //插件集合
                "presets": [
                  [
                    "@babel/preset-env",
                     babel 7.3
                     {
                       "targets": {//浏览器兼容版本
                         "chrome": "58",
                         "ie": "11"
                       },
                       "useBuiltIns": "usage"//该配置项下方详解
                     }
                  ],
                  "@babel/preset-react"
                ],
            }
        }
    }
}

useBuiltIns: 参数有 “entry”、”usage”、false 三个值

默认值是false,此参数决定了babel打包时如何处理@babel/polyfilll 语句。

  • “entry”: 会将文件中 import @babel/polyfilll 语句 结合 targets ,转换为一系列引入语句,去掉目标浏览器已支持的 polyfilll 模块,不管代码里有没有用到,只要目标浏览器不支持都会引入对应的 polyfilll 模块。

  • “usage”: 不需要手动在代码里写 import @babel/polyfilll,打包时会自动根据实际代码的使用情况,结合 targets 引入代码里实际用到部分 polyfilll 模块

  • false: 对 import‘@babel/polyfilll’不作任何处理,也不会自动引入 polyfilll 模块。

需要注意的是在 webpack 打包文件配置的 entry 中引入的 @babel/polyfill 不会根据 useBuiltIns 配置任何转换处理。

除非是不得已不需要通过 import @babel/polyfill一次将所有的polyfill文件引入

core.js@3

可以用来转化一些高级语法,很多@babel/polyfill的proset-env 做不到的就需要依赖 core.js@3这个包

core-js是我们能够使用新的API的最重要的包,然而一般情况它隐藏在webpack编译后的代码中,我们一般不会去查看,所以容易被遗忘,我们在webpack生成环境下,查看编译后的代码,可以看到例如includes就是从core-js导出到我们的代码去的。

core-js是什么
  • 它是JavaScript标准库的polyfill
  • 它尽可能的进行模块化,让你能选择你需要的功能
  • 它可以不污染全局空间
  • 它和babel高度集成,可以对core-js的引入进行最大程度的优化
升级core-js@3动机

目前我们使用的都默认是core-js@2,它在 2018年 之前就封锁了分支,至此之后的特性都只会添加到core-js@3,这里有一个生产例子,使用了core-js@2不支持的新特性,导致错误

  • core-js@2出现的问题
  • Vue-cli使用flat报错
  • vue-cli也会在V4升级core-js
  • Roadmap for Vue-cli4
  • core-js@3添加的特性
core-js@3 特性概览
  • 支持ECMAScript稳定功能,引入core-js@3冻结期间的新功能,比如flat
  • 加入到ES2016-ES2019中的提案,现在已经被标记为稳定功能
  • 更新了提案的实现,增加了proposals配置项,由于提案阶段不稳定,需要谨慎使用
  • 增加了对一些web标准的支持,比如URL 和 URLSearchParams
  • 现在支持原型方法,同时不污染原型
  • 删除了过时的特性
core-js@3 与 babel

以前我们实现API的时候,会引入整个polyfill,其实polyfill只是包括了以下两个包

core-js
regenerator-runtime //包含promise的包

core-js@3 升级之后弃用了@babel/polyfill,以下是等价实现

首先需要手动安装一下core-js@3

// babel.config.js
presets: [
  ["@babel/preset-env", {
    useBuiltIns: "entry", // or "usage",见如下说明
    corejs: "3",
  }]
]

// 如果 useBuiltIns: "entry" 需要在打包入口文件导入两个包:
import "core-js/stable"
import "regenerator-runtime/runtime"

// 如果 useBuiltIns: "usage",不需要在入口文件里导入包了
总结

core-js@3 废弃了 babel-polyfill,实现了完全无污染的API转译,非常有潜力,但是其暂时会增加打包体积,这个还得看未来普及度上来之后的权衡

clean-webpack-plugin

安装:

yarn add clean-webpack-plugin --dev

这个插件用于将我们每次build时之前的导出目录进行删除

使用:

const { CleanWebpackPlugin } = require('clean-webpack-plugin')


plugin:[
    new CleanWebpackPlugin()
]

postcss-loader

用于给样式添加前缀,类似于根据浏览器内核的命名
安装:

yarn add postcss-loader

安装依赖:

yarn add postcss-preset-env --dev

配置:需要配置到匹配样式的rules下

{
    loader: "postcss-loader",
    options: {
        ident: "postcss",
        plugins: () => [require("postcss-preset-env")()]
    }
}

url-loader file-loader

用于匹配图片文件的loader
安装:

yarn add url-loader file-loader --dev 
{
    test: /\.(jpg|jpeg|png|gif)$/,
    use: {
        loader: 'url-loader',
        options: {
            limit: 8000000,//如果文件大小超过该大小则不放入指定目录
            name: '[name]-[hash:6].[ext]',
            outputPath: 'images/'//保存目录
        }
    }
},

对vue、react框架的引入

react

安装 react 和 react-dom

yarn add react react-dom

在入口文件entry中引入react和react-dom

import React from 'react'
import ReactDom from 'react-dom'

创建一个组件App.jsx,因为webpack目前还不支持识别jsx,我们需要将之前的配置进行改变

{
    test: /\.jsx?$/,
    //更改文件匹配
    use: {
        loader: 'babel-loader',
        options: {
           presets:[
                '@babel/preset-env',
                '@babel/preset-react'//需要添加这个预设
           ]
        }
    }
},

安装 @babel/preset-react
用于解析jsx语法

yarn add @babel/preset-react --dev

在模板文件中的根节点添加id 为 root

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

入口文件配置:

import React from 'react'
import ReactDom from 'react-dom'

import App from '../components/App.jsx'
import '../style/common.scss'


ReactDom.render(
    <App></App>,
    document.querySelector('#root')
)
对vue的引入

这里需要使用到vue-loader
在使用vue-loader的时候需要引入两个包

yarn add vue-loader vue-template-compiler --dev

并且在webpack.config文件中引入,然后在配置文件中添加vue-loader,再添加相应plugin

const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  module: {
    rules: [
      // ... 其它规则
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    // 请确保引入这个插件!
    new VueLoaderPlugin()
  ]
}

resolve.extensions

自动解析确定的扩展。

该配置项属于resolve项

alias 别名配置

在config文件中创建resolve项

module.export={
    resolve:{
        alias: {
            '@':path.resolve(__dirname,'./src/components')
        }
    },
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值