前端基础之工程化配置

初识打包工具

grunt/gulp

区别:

  • gulp的核心是task

  • 我们可以配合一系列的task,并且定义task要处理的事务(例如ES6、ts转换,图片压缩,scss转成css),之后让grunt/gulp来一次执行这些task,而且让整个流程自动化,所以grunt/gulp也被称为全段自动任务管理工具

  • task就是将src 下面的所有js文件转成ES5的语法,并且最终输出到dist文件夹中.

什么时候使用grunt/gulp呢?

  • 如果你得工程模块依赖非常简单,甚至是没有用到模块化的概念。
  • 只需要进行简单的合并、压缩,就使用grunt/gulp即可。
  • 但如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的webpack了

所以,grunt/gulp和webpack有什么不同呢?

grunt/gulp 更加强调的是前端流程的自动化,模块化不是它的核心
webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是它附带的功能


配置安装

全局安装:

npm install webpack --save-dev -g
npm install webpack webpack-cli --save-dev

在使用的时候需要进行本地安装:(必须)

npm install webpack --save-dev      
npm install webpack-cli --save-dev

或 npm i webpack webpack-cli -D

指定版本安装:

npm  install  webpack@3.5.5   -g  

查看版本号:

webpack --version

全局webpack和局部webpack

1、在全局安装一个webpack之后,在本地再安装一个webpack避免版本不兼容导致编译错误

npm install webpack@3.6.0 --save-dev

2.再次打开package.json文件

"devDependencies": {
  "webpack": "^3.6.0"
}

3.如果在package.json文件添加"build": "webpack"则优先执行本地的webpack

安装报错处理:

刚开始默认装的webpack4.41.5的,webpack时报错,按照提示也无法解决

于是换了版本,先卸载

npm  uninstall  webpack  -g

在安装指定版本 ,我装的是3.5.5

npm  install  webpack@3.5.5   -g

但是上面指令依然报错:

解决办法,将安装指令换为:npm  install  webpack@3.5.5 -g  --unsafe-perm
成功解决问题。


目录结构

myapp
    |__dist
    |   |__styles
    |   |__js
    |       |__bundle.js
    |   |__index.html
    |__src
    |   |__component
    |   |__index.js
    |__node_modules
    |__package.json
    |__webpack.config.js

1、npm init -Y 生成package.json文件和node_model文件夹

package.json文件主要用于webpack处理指令的定义和外部插件的引入

详解package.json中命令:

webpack-dev-server   //启动webpack-dev-server
--progress --colors    //打包进行显示颜色
--hot  //开启模块热修复功能
--content-base ./dist   //设置webpack-dev-server运行的根目录是 ./dist
--inline  //使用inline的方式进行页面自动刷新
--quiet  //控制台中不输出打包信息
--compress  //开启gzip压缩
node_model文件夹用于存储所有的工具模块

2、创建src和dist文件夹

src文件夹用于保存静态资源——打包前的文件
dist文件夹用于保存打包后的文件

3、创建webpack.config.js文件

webpack.config.js 文件用于统一配置webpack功能模块

包含:

const {resolve} = require('path') // 使用node的绝对路径模块
// 或 const path = require('path') // 使用node的绝对路径模块path.resolve
const HtmlWebPlugin = require('html-webpack-plugin') // 引入处理HTML文件的插件
module.exports = {
  // entry: resolve(__dirname + "./src/main.js")
  // entry: ["./src/main.js","./src/index.js"] // 多文件入口文件 数组形式
  entry: {
    main: "./src/main.js",
    index: "./src/index.js"
  }, // 多文件入口文件对象形式
  output: { // 文件打包后输出口
      path: resolve(__dirname + "/dist"), //打包后的文件存放的地方
      filename: "[name]-[hash].js" // 打包后输出文件的文件名
      // filename: "name.js" // 单文件输入出
  },
  module: { // 安装loader
    rules: [
      {
        test: /\.css$/,   // 正则匹配以.css结尾的文件
        use: ['style-loader', 'css-loader']  // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
      },
      {
        test: /\.less$/,   // 正则匹配以.css结尾的文件
        use: ['style-loader', 'css-loader', 'less-loader']  // 需要用的loader,一定是这个顺序,因为调用loader是从右往左编译的
      }
    ]
  },
  plugins: [  // 插件管理
    new HtmlWebPlugin({ // HTML文件处理插件
      template: './src/index.html'
    })
  ],
  resolve: { //其他解决方案配置
     extensions: ['', '.js', '.json', '.css', '.scss']//添加在此的后缀所对应的文件可以省略后缀
  },
  devServer: { //设置本地服务的端口号,不设置则默认为8080端口
     contentBase: "./dist", // 本地服务器所加载文件的目录
     port: "8088",   // 设置端口号为8088
     inline: true, // 文件修改后实时刷新
     historyApiFallback: true, //不跳转
  },
  mode: 'development' // development开发环境、production生产环境
}

打包指令及相关配置

执行方式一:

webpack4.0之前的执行方式

webpack .\src\main.js   -o    .\dist\bundle.js
              需要打包的js   兼容   生成的新的js

webpack4.0之后的执行方式

webpack src/index.js --output dist/bundle.js

执行方式二:通过webpack命令执行打包

// 1. 创建webpack.config.js文件
const path = require('path')
module.exports = {
  entry: './src/main.js', // 入口路径
  output: { // 出口路径
    path: path.resolve(__dirname, 'dist'), // 动态获取路径
    filename: 'bundle.js',
    publicPath: 'dist/' // 如果出现url引用资源自动更改路径
  }
}
// 2. npm init // 初始化生成page.json文件
// 3. npm install // 加载npm包依赖

执行方式三:在执行方式二的基础上配置package.json文件

package.json文件添加"build": "webpack"之后可以执行npm run build来打包

 "scripts": {
    "buid": "webpack" // build指令可以自定义,如果是start则比较特殊,运行的时候不需要run指令:npm start
  }

解决webpack因新版本打包失败问题--ERROR in multi ./src/main.js ./dist/bundle.js
最近在学习webpack打包过程中遇到的一个问题向大家分享下!
创建了一个webpacksty的目录,目录下放着dist,src子目录,然后通过node环境下,npm init -y 初始化项目出现package.json文件,src子目录下又存放着index.html和main.js文件,接下来尝试着在main.js输入一句代码当验证打包后续是否成功的过程:
console.log("ok");
  
接下就是执行webpack打包命令了
把src下的main.js打包到dist下的bundle.js,执行命令:
webpack .\src\main.js .\dist\bundle.js
执行后:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J32qn4Fq-1648807954349)(/Web/Notes/images/webpack1.png)]

报错了!此时也可以直接看出我的webpack版本号:4.30.0 ,算是新版本了。
当然此时查看结构目录下dist肯定没有bundle.js的文件出现,然后自己也是看别人的博客查询到了原来是版本过高,以前的命令已经不适用了,只要加-o就轻松解决原来。
webpack .\src\main.js -o .\dist\bundle.js
此时就执行成功了!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TSGDTP5C-1648807954350)(/Web/Notes/images/webpack2.png)]

在dist目录下也自动生成了bundle.js的文件。


常用的loader

样式处理:

// css-loader负责将css文件进行加载
npm install css-loader --save-dev
// style-loader负责将样式添加到DOM中
npm install style-loader --save-dev

npm i sass-loader node-sass --save-dev

*node-sass最近几个版本安装可能会报错,我今天就遇到,github也有网友反映了这问题(见上篇)
*使用sass要先安装ruby,然后命令行gem sass (这不影响我们在项目的webpack中使用sass)

npm install less-loader --save-dev

// 解决CSS3兼容性
npm i postcss-loader autoprefixer --save-dev
npm i postcss postcss-loader postcss-preset-env -D

ES6处理:

npm install --save-dev babel-loader babel-core 
npm install babel-preset-env --save-dev

或者制定版本号

npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['es2015']
        }
      }
    }
  ]
}
当用到promise、map、或者ES6数组方法的时候
babel 默认只转换新的 JavaScript 语法,
不转换新的API以及一些定义在全局对象上的方法,
如果想使用这些新的对象和方法,则需要为当前环境提供一个垫片polyfill

第一步:

npm install --save babel-polyfill

第二步:创建.babelrc文件

{
  "presets": ["env"]
}

第三步:

babel-polyfill用正确的姿势安装之后,引用方式有三种:

require("babel-polyfill");
import "babel-polyfill";
module.exports = {
  entry: ["babel-polyfill", "./app/js"]
};

文件处理:

然后是文件方面的,帮我们处理图片等:
npm i file-loader url-loader --save-dev

在webpack上处理图片的时候,难免会因为路径问题困惑。
我们知道项目中引用图片有以下几种情景:

  1. html的<img src=' ' >
  2. css中背景图片引用
  3. js中动态创建/生成img
  4. 行内样式中设置background-image

在webpack使用file-loader对图片打包时:

  1. 用html-withimg-loader配合htmlWebpackPlugin(见下边代码蓝色部分)
  2. css的路径会自动替换
  3. js中引用图片的src时,要用require()

图片文件打包

  1. 在main.js中引用

  2. 安装loader

npm install url-loader --save-dev
npm install file-loader --save-dev
npm install html-withimg-loader --save-dev
var html = require('html-withimg-loader!./xxx.html');
  1. 配置
module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
        outputpath: '' // 指定输出路径
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              // 设置引入资源的大小,
              // 当加载的图片小于limit时候,会将图片编译成base64字符串形式;
              // 当加载的图片大于limit时候,需要使用file-loader模块进行加载
              limit: 8 * 1024, // 转化为base64的图片比正常图片要大
              name: 'img/[name].[hash:8].[ext]' // 图片资源命名
            }
          },
          {
     	   loader: 'file-loader'
          }
        ]
      },
      {
           test: /\.(htm?l)/i,
           use: {loader: 'html-withimg-loader'}
       }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
        template: 'html-withimg-loader!' + path.resolve(srcDir, filename),
        filename: filename
    }),
  ]
  4. 设置
    output: {
    ...
    publicPath: 'dist/'
    }

可以在打包时候自动更改图片的路径

Vue文件编译处理

安装:

npm install vue-loader vue-template-compiler --save-dev

配置:

{
test: '/\.vue$',
use: ['vue-loader']
}

其他资源处理

npm i file-loader --save-dev
配置:
{ test: Condition }:匹配特定条件。一般是提供一个正则表达式或正则表达式的数组,但这不是强制的。
{ include: Condition }:匹配特定条件。一般是提供一个字符串或者字符串数组,但这不是强制的。
{ exclude: Condition }:排除特定条件。一般是提供一个字符串或字符串数组,但这不是强制的。
{ and: [Condition] }:必须匹配数组中的所有条件
{ or: [Condition] }:匹配数组中任何一个条件
{ not: [Condition] }:必须排除这个条件

配置开发环境或者生产环境的兼容性问题

 "browserslist": {
    // 开发环境 --> 设置node环境变量:process.env.    NODE_ENV = development
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    // 生产环境:默认是看生产环境
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  }

plugin插件

  • plugin是插件,通常是用于对某个现有框架进行扩展。
  • loader和plugin区别
  • loader主要用于转换某些类型的模块,它是一个转换器。
  • plugin是插件,它是对webpack本身的扩展,是一个扩展器。

CSS文件分离插件 mini-css-extract-plugin
配置

const HtmlWebpackPlugin = require('html-webpack-plugin'); // HTML处理插件
const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); // CSS处理插件
const webpack = require('webpack'); //访问内置的插件
const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    filename: 'my-first-webpack.bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader'
      }
    ]
  },
  plugins: [
    new webpack.ProgressPlugin({ // HTML处理
        template: 'index.html'
    }),
    new HtmlWebPlugin({ // HTML文件处理
      template: './src/index.html' // 复制index.html文件
    }),
    new MiniCSSExtractPlugin(), // 样式处理
    new webpack.BannerPlugin({ // 添加横幅
      banner: 'hello world'
    })
  ]
};

压缩丑化uglifyjs-webpack-plugin

下载:

npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

配置:

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [new UglifyJsPlugin()],
  },
};

下载:
npm install webpack-dev-server@2.9.3 --save-dev

配置:

// webpack.config.js
devServer: {
  contentBase: './dist/, // 为哪个文件夹提供本地服务
  port: 8080, // 指定端口号
  inline: true, // 页面实时刷新
  compress: true,// 是否开启服务端压缩(gzip)
  // historyApiFallback 在SPA页面,依赖HTML5的history模式
}

// pages.js

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

配置分离

关于mode

webpack根据开发和生成环境一般可以将配置文件拆分,拆分dev和prod两种环境

|- package.json
  |- /build
    |- webpack.base.js
    |- webpack.dev.js
    |- webpack.prod.js

在scripts里修改相应的命令

"dev": "webpack-dev-server --config build/webpack.dev.js",
"build": "webpack --config build/webpack.prod.js"

使用webpack-merge,用以合并通用配置文件与开发环境配置文件

// webpack.dev.js
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base');

module.exports = merge(baseWebpackConfig, {
  mode: 'development',
  devServer: {
    host: '127.0.0.1',
    port: 80,
    contentBase: path.join(__dirname, 'dist'),
    open: false,
    hot: false,
    disableHostCheck: true,
    proxy: {},
    before () {}
  },
  plugins: [
    // 启用 HMR
    new webpack.HotModuleReplacementPlugin({})
  ]
});
// webpack.prod.js
const baseWebpackConfig = require('./webpack.base');
module.exports = merge(baseWebpackConfig, {
  mode: 'production'
});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值