从0搭建本身的webpack开发环境(一)

上期文章:前端自动化测试javascript

又一个连载来啦!此次咱们将分四篇文章来介绍如何从0构建一个webpack开发环境,了解其内部机制和原理,从而让咱们更准确的掌握和使用webpack,下面开始咱们的起步:html

1.什么是Webpack?

webpack是一个现代 JavaScript 应用程序的静态模块打包器(module bundler),当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序须要的每一个模块,而后将全部这些模块打包成一个或多个 bundle前端

图片

使用Webpack做为前端构建工具:java

  • 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等;
  • 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等;
  • 代码分割:提取多个页面的公共代码、提取首屏不须要执行部分的代码让其异步加载;
  • 模块合并:在采用模块化的项目里会有不少个模块和文件,须要构建功能把模块分类合并成一个文件;
  • 自动刷新:监听本地源代码的变化,自动从新构建、刷新浏览器;
  • 代码校验:在代码被提交到仓库前须要校验代码是否符合规范,以及单元测试是否经过;
  • 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

webpack应用中有两个核心:node

    1. 模块转换器,用于把模块原内容按照需求转换成新内容,能够加载非 JS 模块;
    1. 扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或作你想要的事情。

2.初始化项目

├── src   # 源码目录
│   ├── a-module.js
│   └── index.js
复制代码

编写 a-module.jsjquery

module.exports = 'hello';
复制代码

编写 index.jswebpack

let a = require('./a-module');
console.log(a);
复制代码

这里咱们使用CommonJS模块的方式引入,这种方式默认在浏览器上是没法运行的,咱们但愿经过 webpack 来进行打包!web

3.webpack快速上手

3.1 安装

npm init -y
npm install webpack webpack-cli --save-dev
复制代码

webpack默认支持0配置,配置scripts脚本npm

"scripts": {
  "build": "webpack"
}
复制代码

执行npm run build,默认会调用 node_modules/.bin下的webpack命令,内部会调用webpack-cli解析用户参数进行打包。默认会以 src/index.js 做为入口文件。json

这里也可使用npx webpacknpx 是 5.2版本以后npm提供的命令能够执行.bin下的可执行文件

图片

咱们发现已经产生了dist目录,此目录为最终打包出的结果。main.js能够在html中直接引用,这里还提示咱们默认modeproduction

3.2 webpack.config.js

咱们打包时通常不会采用0配置,webpack在打包时默认会查找当前目录下的 webpack.config.js or webpackfile.js 文件。

经过配置文件进行打包:

const path = require('path');
module.exports = {
    entry:'./src/index.js',
    output:{
        filename:'bundle.js', 
        // 打包出的结果文件
        path:path.resolve(__dirname,'dist')// 打包到dist目录下
    }
}
复制代码

3.3 配置打包的mode

咱们须要在打包时提供mode属性来区分是开发环境仍是生产环境,来实现配置文件的拆分。

├── build
│   ├── webpack.base.js
│   ├── webpack.dev.js
│   └── webpack.prod.js
复制代码

咱们能够经过指定不一样的文件来进行打包

配置scripts脚本:

"scripts": {
  "build": "webpack --config ./build/webpack.prod",
  "dev": "webpack --config ./build/webpack.dev"
}
复制代码

能够经过 config 参数指定,使用哪一个配置文件来进行打包。

经过env参数区分

"scripts": {
    "build": "webpack --env.production --config ./build/webpack.base",
    "dev": "webpack --env.development --config ./build/webpack.base"
}
复制代码

改造webpack.base文件默认导出函数,会将环境变量传入到函数的参数中。

module.exports = (env)=>{
    console.log(env); // { development: true }
}
复制代码

合并配置文件

咱们能够判断当前环境是不是开发环境来加载不一样的配置,这里咱们须要作配置合并 安装webpack-merge:

npm install webpack-merge --save-dev
复制代码

webpack.dev配置

module.exports = {
    mode:'development'
}
复制代码

webpack.prod配置

module.exports = {
    mode:'production'
}
复制代码

webpack.base配置

const path = require('path');
const merge = require('webpack-merge');
// 开发环境
const dev = require('./webpack.dev');
// 生产环境
const prod = require('./webpack.prod');
const base = { 
    // 基础配置
    entry:'./src/index.js',
    output:{
        filename:'bundle.js',
        path:path.resolve(__dirname,'../dist')
    }
}
module.exports = (env) =>{
    if(env.development){
        return merge(base,dev);
    }else{
        return merge(base,prod);
    }
}
复制代码

后续开发中,咱们会将公共的逻辑放到base中,开发和生产中的配置也分别进行存放!

4.webpack-dev-server

配置开发服务器,能够在实如今内存中打包,而且自动启动服务。

npm install webpack-dev-server --save-dev
复制代码
"scripts": {
    "build": "webpack --env.production --config ./build/webpack.base",
    "dev": "webpack-dev-server --env.development --config ./build/webpack.base"
}
复制代码

经过执行npm run dev来启启动开发环境:

webpack2

默认会在当前根目录下启动服务

配置开发服务的配置

const path = require('path')
module.exports = {
    mode:'development',
    devServer:{
        // 更改静态文件目录位置
        contentBase:path.resolve(__dirname,'../dist'),
        compress:true, // 开启gzip
        port:3000, // 更改端口号
    }
}
复制代码

5.打包Html插件

5.1 单入口打包

自动产生html,而且引入打包后的文件

编辑webpack.base文件

const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins:[
    new HtmlWebpackPlugin({
        filename:'index.html', // 打包出来的文件名
        template:path.resolve(__dirname,'../public/index.html'),
        hash:true, // 在引用资源的后面增长hash戳
        minify:{
            removeAttributeQuotes:true // 删除属性双引号
        }
    })
]
复制代码

5.2 多入口打包

根据不一样入口生成多个js文件,引入到不一样html中:

── src
    ├── entry-1.js
    └── entry-2.js
复制代码

多入口须要配置多个entry

entry:{
    jquery:['jquery'], // 打包jquery
    entry1:path.resolve(__dirname,'../src/entry-1.js'),
    entry2:path.resolve(__dirname,'../src/entry-2.js')
},
output:{
    filename:'[name].js',
    path:path.resolve(__dirname,'../dist')
},
复制代码

产生多个html文件

new HtmlWebpackPlugin({
    filename:'index.html',
    template:path.resolve(__dirname,'../public/template.html'),
    hash:true,
    minify:{
        removeAttributeQuotes:true
    },
    chunks:['jquery','entry1'], // 引入的chunk 有jquery,entry
}),
new HtmlWebpackPlugin({
    filename:'login.html',
    template:path.resolve(__dirname,'../public/template.html'),
    hash:true,
    minify:{
        removeAttributeQuotes:true
    },
    inject:false, // inject 为false表示不注入js文件
    chunksSortMode:'manual', // 手动配置代码块顺序
    chunks:['entry2','jquery']
})
复制代码

以上的方式不是很优雅,每次都须要手动添加HtmlPlugin应该动态产生html文件,像这样:

let htmlPlugins = [
  {
    entry: "entry1",
    html: "index.html"
  },
  {
    entry: "entry2",
    html: "login.html"
  }
].map(
  item =>
    new HtmlWebpackPlugin({
      filename: item.html,
      template: path.resolve(__dirname, "../public/template.html"),
      hash: true,
      minify: {
        removeAttributeQuotes: true
      },
      chunks: ["jquery", item.entry]
    })
);
plugins: [...htmlPlugins]
复制代码

6.清空打包结果

可使用clean-webpack-plugin手动清除某个文件夹内容:

安装

npm install --save-dev clean-webpack-plugin
复制代码
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
new CleanWebpackPlugin({
    // 清空匹配的路径
    cleanOnceBeforeBuildPatterns: [path.resolve('xxxx/*'),'**/*'],
})
复制代码

这样就能够清空指定的目录了,咱们能够看到webpack插件的基本用法就是 new Plugin而且放到plugins中。

7.小结

如今是否是对webpack的使用有了初步印象或更多的想法了呢?大神们的大刀是否是快要按捺不住了呢?下期介绍webpack不得不会的各类配置,敬请期待!


前端优选
相关文章
相关标签/搜索