如何用webpack打包各种资源🤷‍♀️

703 阅读4分钟

webpack基础

webpack五个核心概念

1. Entry

入口(Entry)指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图;比如以index.js文件为入口文件,这个文件分别以来哪些文件,把这些文件加载进来并进行处理;

2. Output

输出(Output)指示webpack打包后的资源bundles输出到哪里去,以及如何命名;

3. Loader

Loader让webpack能够处理非JavaScript(如css、img等文件类型);webpack自身只能读取JavaScript

4. Plugins

插件(Plugins)可以用于执行范围更广的任务。插件的范围包括:从打包优化和压缩,一直到重新定义环境中的变量等。

打包读取文件之后输出;

5. Mode

  • 开发模式(development):代码在本地就能运行
  • 生产模式(production):代码优化上线运行的环境

开发模式的配置相对简单,生产模式的相对复杂,提高用户体验感;

webpack的基础使用

打包前的文件(如起点文件index.js)放入src文件夹中,打包后的文件放在build文件夹中;后执行下面的指令打包

  1. 运行指令:

    • 开发环境:webpack ./src/index.js -o ./build/built.js --mode=development webpack会以./src/index.js为入口文件开始打包,打包后输出到./build/built.js整体打包环境
    • webpack ./src/index.js -o ./build/built.js --mode=production,打包后会压缩js代码;
  2. 打包之后在html文件中引入打包后资源,每一次修改入口文件都要重新进行打包;

    • webpack能处理js/json,不能处理img/css等其他资源
    • 生产环境和开发环境将ES6模块化编译成浏览器识别的模块化
    • 生产环境比开发环境多一个压缩js代码

打包非JavaScript资源

创建webpack的配置文件:webpack.config.js

  • 指示webpack去做什么,当运行webpack指令的时候,会加载里面的配置
  • 所有构建工具都是基于nodejs平台运行的~模块化默认采用commonjs
const { resolve } = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',   // 打包好的文件
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: []
    },
    plugins: [],
    mode: 'development',
}

1. 打包样式资源

如果要加载css文件,就要在module里面设置一个规则,当有css文件的时候就要使用style-loader以及css-loader’;user数组中loader执行顺序:从右到左,从下到上依次进行

  • style-loader能够创建一个style标签,将js中的样式资源插入进行,再添加到head中生效;
  • css-loader将css文件变成commonjs模块加载到js中,里面内容是样式字符串;
module: {
    rules: [ {
            test: /.css$/,
            use: [
                'style-loader',  
                'css-loader'
            ] } ]
},

不同文件必须配置不同的loader进行处理,比如对于less文件,less-loader会将less文件编译成css文件;注意:一些包和loader都需要自己手动去下载,比如lessless-loader都需要下载;

test: /.css$/,
use: [
    'style-loader', 
    'css-loader',
    'less-loader'
]

2. 打包html资源

  • 打包html资源需要下载插件:npm i html-webpack-plugin -D,下载后在入口文件中引入;
  • 功能:默认会创建一个空的HTML,自动引入打包输出所有资源(JS/CSS);也就是这个src中的index.html文件打包的时候会自动引入到build中的html文件中;
const htmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
    new htmlWebpackPlugin({
        template: './src/index.html'
    })
],

3. 打包图片资源

  • loader能够通过options去进行配置

  • 比如下面的limit: 8*1024表示当图片小于8kb时就会被base64(该图片会被编译成一种字符串)处理;而name是给图片重命名,[hash: 10]取图片hash的前10位,[ext]取文件原来的扩展名

    优点:减少请求数量,减少服务器压力;

    缺点:图片体积会更大,文件请求速度变慢

  • 需要下载两个包:url-loaderfile-loader

test: /.(jpg|png|gif)$/,
loader: 'url-loader', 
options: {
    limit: 8*1024
    name: '[hash:10].[ext]'
}
  • 默认处理不了html中的img图片,此时如果要加载html中的图片,那么就要对html进行处理,

  • 负责引入img,从而能被url-loader进行处理

    test: /.html$/,
    loader: 'html-loader', 
    options: {
        esModule: false
    }
    
  • 此时会出现一个问题:url-loader默认使用es6模块化解析,而html-loader引入图片是commonjs;此时我们要关闭html-loader的commonjs模块化,用es6模块化进行解析;

4. 打包其他资源

下面这段代码表示除了html/css/js以外的资源都会在这里被读取到;

{
    exclude: /.(css|js|html)$/,
    loader: 'file-loader'
}

derServer

  • 开发服务器devServer:用来自动化,自动打开浏览器和刷新浏览器;就不用每次都重新打包了;
  • 特点:只会在内存中编译打包,不会有任何的输出
  • 启动dev-Server指令为:npx webpack-dev-server(这个要手动下载)
devServer: {
    contentBase: resolve(__dirname, 'build');
    compress: true,
    port: 3000  // 端口号
}