webpack4.0基础篇

webpack就是为打包而生的。css

1、准备

学习webpack首先须要安装nodejs,而且做者也强调新版本的nodejs会提升webpack的打包速度。
安装好node后就能够在项目命令行中执行下面的代码html

npm init

而后根据须要设置,也能够一直回车,固然若是都使用默认配置也能够node

npm init -y

这样就能够在项目中生成package.json文件了。这样作的目的就是为了使项目符合node规范。linux


2、安装webpack

安装webpack有两种方式
1.全局安装webpack(不推荐)
在命令行中输入webpack

npm install webpack webpack-cli -g

安装成功后能够经过命令 webpack -v查看是否安装成功
可是很是不推荐全局方式安装webpack,由于若是机器上有多项目用不一样版本webpack就没法作到兼容。
全局卸载webpackcss3

npm uninstall webpack webpack-cli -g

2.项目内安装webpack(==推荐==)
命令行进入项目目录,执行下面命令es6

npm install webpack webpack-cli -D

这种方式安装成功后没法经过webpack -v查看webpack版本信息,由于默认node会查找全局下的webpack。这里就要经过npx命令查看。web

npx webpack -v

npx命令会在当前项目的node_modules中找到咱们安装的webpack正则表达式

3.安装制定版本webpackchrome

npm install webpack@4.16.0

能够经过webpack info 查看全部版本


3、开始打包

安装好webpack后就能够开始打包咱们的项目代码了,如咱们项目中有一个xxx.js文件。

npx webpack xxx.js

这样就会将某一个js文件进行打包,打包后的文件就存放在项目根目录的dist文件夹中。这样就是webpack最基础的打包方式,使用的也是webpack默认的配置。若是想要更多的功能就要在webpack.config.js文件中进行配置


4、配置文件

在项目根目录中新建一个webpack.config.js文件。

const path = require('path');

module.exports = {
    mode: 'production', // 打包模式,production为生产模式,development为开发模式 开发模式下js不会被压缩
    // entry: 指定入口文件,
    entry: { // 打包输出两个文件
        home: './src/index.js',
        index: './src/index.js'
    },
    output: { // 输入配置
        publicPath:'http://cdn.com.cn',// 指定打包的文件前缀地址
        filename:'[name].js', // 打包后的文件名,可使用placeholder占位符方式,[name]获取到entry中配置的名称
        path: path.resolve(__dirname, 'dist') // 打包好的文件夹,默认就是dist
    }
}

这就是最近本的打包配置,指定的打包模式,入口,输出配置等。
配置好后就能够经过

npx webpack

直接运行,不用再写具体文件,而是经过配置的入口去找到指定文件。
webpack.config.js 是webpack默认的配置文件,固然也能够手动修改
命令行执行以下面命令便可,npx webpack --config webpackconfig2.js

在平时开发的时候可能不多有人用到npx webpack这种命令进行打包,这是由于在package.json文件中对打包命令进行了简化,在scripts中添加以下代码

"scripts": {
   "bundle": "webpack"
},

这样改写后执行npm run bundle 至关于执行了webpack打包命令。
在scripts中使用webpack会优先在项目的node_modules中找webpack。

咱们以前在安装webpack的时候,安装了一个webpack-cli,这个webpack-cli包的做用就是让咱们能够在命令行中运行webpack命令(npx webpack等命令)。


5、loader

webpack的做用就是打包,可是webpack只能识别js文件,若是咱们的js文件中引入了样式,或者尝试打包一个css文件、图片文件等,那么webpack就会报错。由于webpack不知道如何处理这样的文件。这时webpack就须要一个东西帮他处理,就是loader。
==loader就是帮助webpack打包不能识别的文件==

打包css

css-loader & style-loader

const path = require('path');

module.exports = {
    mode: ……
    entry: ……,
    output: ……,
    module:{
        rules:[
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            }
        ]
    } 
}

想打包css文件就要安装style-loader和css-loader。

npm install style-loader css-loader -D

rules数组中就是不少打包规则,经过正则表达式匹配到css文件,而后告诉webpack一旦遇到css文件就使用style-loadercss-loader处理。
css-loader的做用是帮助webpack识别css。分析文件关系,而后合并。
style-loader的做用是获得css-loader分析出来的结果,将css挂载到html-header-style中。
==因此loader的调用是有顺序的,顺序是从后向前==,先执行css-loader再执行style-loader。

sass-loader
打包sass文件须要用到sass-loader。首先安装sass-loader和node-sass。
npm i sass-loader node-sass -D
而后改动一下rules

rules:[
    {
        test: /\.css$/,
        use: [
                'style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        importLoaders: 1,
                        modules: true // 默认false,引入的css属于全局的样式,开启true后,css变为模块化,引入css时能够经过style.xxx
                    }
                },
                'sass-loader'
            ]
    }
]

sass-loader的调用必定要在css-loader以前,因此要放到数组最后。可是若是一个scss文件中经过import了另外一个scss文件,那么在打包第二个scss文件就会直接走到css-loader,致使打包失败。因此要在css-loaderoptions中加入importLoaders,表示走css-loader前还要走另一个loader。

postcss-loader
postcss-loader能够自动添加css3前缀,须要新建一个postcss.config.js文件,而且要安装插件, npm i autoprefixed -D
将postcss-loader放到rules中sass-loader以前执行,也就是数组最后。
postcss.config.js

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

这样咱们在打包css代码时,就会自动添加css3前缀。由于autoprefixer中内置了浏览器兼容表,默认>5%兼容。

打包文件

file-loader & url-loader
先安装npm i file-loader -D。打包图片文件以下

rules: [
    {
        test: /\.(jpg|png|gif)$/,
        use: {
            loader: 'file-loader',
            option: {
                name: '[name]_[hash].[ext]',
                outputPath: 'images/'
             }
        }
    }
]

name命名使用placeholder-占位符,不指定则打包后的文件是随机生成的名字。
对于特别小的图片,可使用url-loader打包成base64格式放到js文件中。
先安装npm i url-loader -D,file-loader的功能url-loader一样也能够实现,经过配置大小限制,若是超过则使用传统方式打包,不然就使用base64方式打包,十分方便。

rules: [
    {
        test: /\.(png|jpg|gif)$/,
        use:{
            loader: 'url-loader',
            options:{
                name: '[name]_[hash].[ext]',
                outputPath: 'images/',
                limit: 2048 // 限制文件大小小于2048字节,使用base64方式打包
            }
        }
    }
]
打包es6

安装babel-loader 和 babel/core 包。
npm i babel-loader @babel/core -D
babel-loader是帮助webpack打包的工具
babel/core是babel的核心库。可让babel识别js中的语法,将js语法转换为AST抽象语法树。
添加babel-loader分析js语法,打通babel和webpack,同时还须要借助其余babel模块才能将es6 转换为 es5。安装babel/preset-env
npm i @babel/preset-env -D
如今就能够将es6转换为es5了,可是一些方法在低版本的浏览器中依然不支持。还须要借助polyfill模块。
npm i @babel/polyfill -D
而后在业务代码中引入polyfill
import "@babel/polyfill"
而后改写webpack.config.js

rules: [
    {
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules中的代码
        loader: 'babel-loader',
        options:{
            presets:[["@babel/preset-env"],{
                 targets:{
                     chrome: ">67" // 能够指定兼容浏览器版本
                 },
                 // 当使用polyfill的时候,会将全部特性都加入,而不是根据业务代码决定加什么,致使打包后的文件过大。因此经过以下配置解决这个问题,根据业务代码的须要将使用的特性打包进去
                 useBuiltIns: 'usage'
            }]
        }
    }
]

如今就能够正常打包es6的代码了。不过依然会有一个潜在的问题,就是polyfill再注入方法的时候经过全局变量的形式完成的,会污染全局环境,不适用组件打包。
解决办法:
npm i @babel/plugin-transform-runtime @babel/runtime @babel/runtime-corejs2 -D
在babel options中添加plugins配置。

rules: [
    {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options:{
            // 库代码使用此配置,解决polyfill的问题
            "plugins": [["@babel/plugin-transform-runtime"], {
                "corejs": 2,
                "helpers": true,
                "regenerator": true,
                "useESModules": false
            }]
        }
    }
]

补充:options内的配置能够单独放到.babelrc文件中


6、plugin

plugin相似一些框架中的生命周期函数,在打包特定的时间点触发去作一些事情。

HtmlWebpackPlugin
如html-webpack-plugin是在打包结束后。安装这个插件。
npm i html-webpack-plugin -D
HtmlWebpackPlugin插件会在打包结束后,自动生成一个html文件,并把打包生成的js自动引入到这个html中,html中没有标签。也能够经过模版template,这样在生成html文件时会以配置的html文件为模版生成。

const path = require('path');

module.exports = {
    mode: ……
    entry: ……,
    output: ……,
    module: ……,
    plugins: [
        new HtmlWebpackPlugin({
            // 根据模版生成html文件
            template: 'src/index.html'
        })
    ] 
}

CleanWebpackPlugin
CleanWebpackPlugin插件会在打包前将dist目录删除(非官方)
cnpm i clean-webpack-plugin -D

module.exports = {
    mode: ……
    entry: ……,
    output: ……,
    module: ……,
    plugins: [
        // 从新打包先删除dist目录
        new CleanWebpackPlugin(['dist'])
    ] 
}

7、sourceMap

sourceMap 是一个映射关系,他知道dist目录下main.js文件出错位置,对应的是src下的index.js文件的位置。在webpack.config.js中添加devtool配置。

module.exports = {
    mode: ……
    devtool: 'none'
}

设置devtool: 'none',js报错只会提示在打包后的js文件中,在开发的时候定位错误就变得异常困难。
设置devtool: 'source-map',js报错会显示在原来的文件中,由于在打包后的目录中会生成一个map.js文件,里面存的就是映射关系。报错时经过映射关系找到原文件。
设置devtool: 'inline-source-map',inline这种方式不会生成map文件,而是生成base64字符串保存在打包后的js文件底部。
设置devtool: 'cheap-source-map',如不设置cheap,报错信息会具体到行列,致使映射关系复杂,耗费性能。加上cheap解决这个问题,同时不去处理第三方代码,只处理业务代码。到一些业务须要将咱们本身写的模块或者第三方代码进行处理。那就要用到module。
设置devtool: 'cheap-module-source-map',设置module后解决cheap不处理第三方模块的问题。
设置devtool: 'cheap-module-eval-source-map',设置eval后,不会生成map文件,也不会有base64编码的字符串,而是改变代码的执行方式,经过sourceURL指向原文件。性能最好。
==开发环境最佳实践==:devtool: 'cheap-module-eval-source-map'
==生产环境最佳实践==:devtool: 'cheap-module-source-map'


8、devServer

每次修改后都要从新手动打包,这样很是浪费时间。有三种方式解决这个问题

1.在package.json中添加"watch": "webpack --watch"

scripts:{
   "watch": "webpack --watch"
}

打包的时候运行命令npm run watch
这时webpack就会监听要打包的文件,若是文件变化就会从新打包。

2.配置 devServer
安装dev-server 执行。npm i webpack-dev-server -D
在package.json中添加配置

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

打包的时候运行命令npm run start
同时也能够在webpack.config.js中添加配置,

module.exports = {
    ……
    devServer: {
        contentBase: './dist', // 打包文件目录
        open: true, // 是否自动打开浏览器
        prot: 8080 // 启动服务端口
    }
}

==webpack-dev-server 打包后不会生成dist目录,而是在内存中。提高打包速度==
使用dev-server时能够搭配使用Hot Module Replacement (热模块替换)
引入HotModuleReplacementPlugin插件,可开启hmr功能,hmr能够热更js、css等代码。

module.exports = {
    ……
    devServer: {
        contentBase: './dist', // 打包文件目录
        open: true, // 是否自动打开浏览器
        prot: 8080, // 启动服务端口
        hot: true, // 开启hmr
        hotOnly: true // 阻止浏览器自动刷新
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ],
}

3.本身编写node服务
本身编写服务如server.js ,在package.json中配置server命令
"server": "node server.js",至关于在node中使用webpack
打包时执行命令npm run server便可。

9、总结

webpack基础用法就是这些,文中涉及到的内容足够知足一个小型项目的打包需求。基础用法熟练掌握后,能够经过阅读webpack官方文档进行更详细的打包配置。

相关文章
相关标签/搜索