Webpack速成II


webpack 有四个核心部分

  • entry 规定入口文件,一个或者多个
  • output 规定输出文件的位置
  • loader 各个类型的转换工具
  • plugin 打包过程中各种自定义功能的插件

基础配置

初始化环境

新建 src 目录并在其中新建 index.js ,随便写点 console.log('index js') 。然后根目录创建 webpack.config.js ,内容如下
const path = require('path')

module.exports = {
    // mode 可选 development 或 production ,默认为后者
    // production 会默认压缩代码并进行其他优化(如 tree shaking)
    mode: 'development',
    entry: path.join(__dirname, 'src', 'index'),
    output: {
        filename: 'bundle.js',
        path: path.join(__dirname, 'dist')
    }
}
然后增加 package.json 的 scripts
  "scripts": { "build": "webpack" },

打包上线build

使用 webpack 需要两个最基本的功能:
第一,开发的代码运行一下看看是否有效;
第二,开发完毕了将代码打包出来。
这两个操作的需求、配置都是完全不一样的。例如,运行代码时不需要压缩以便 debug ,而打包代码时就需要压缩以减少文件体积。因此,最好还是把他们区分开
dev——本地运行 build——打包上线
打包上线的例子:
首先,安装 npm i webpack-merge -D ,然后根目录新建 build 目录,其中新建了三个文件:
1.webpack.common.js 公共的配置
const path = require('path')
const srcPath = path.join(__dirname, '..', 'src')
const distPath = path.join(__dirname, '..', 'dist')
module.exports = {
    entry: path.join(srcPath, 'index')
}
2.webpack.dev.js 运行代码的配置
const path = require('path')
const webpackCommonConf = require('./webpack.common.js')
const { smart } = require('webpack-merge')
const srcPath = path.join(__dirname, '..', 'src')
const distPath = path.join(__dirname, '..', 'dist')
module.exports = smart(webpackCommonConf, {
    mode: 'development'
})
3.webpack.prod.js 打包代码的配置
const path = require('path')
const webpackCommonConf = require('./webpack.common.js')
const { smart } = require('webpack-merge')
const srcPath = path.join(__dirname, '..', 'src')
const distPath = path.join(__dirname, '..', 'dist')
module.exports = smart(webpackCommonConf, {
    mode: 'production',
    output: {
        filename: 'bundle.[contentHash:8].js',  // 打包代码时,加上 hash 戳
        path: distPath,
        // publicPath: 'http://cdn.abc.com'  // 修改所有静态文件 url 的前缀(如 cdn 域名),这里暂时用不到
    }
})
在这个例子中,我们要打包上线,因此,修改package.json 中的 scripts:
  "scripts": { "build": "webpack --config build/webpack.prod.js" },

JS模块化

webpack 默认支持 js 各种模块化,如常见的 commonJS 和 ES6 Module 。但是推荐使用 ES6 Module ,因为 production 模式下,ES6 Module 会默认触发 tree shaking ,而 commonJS 则没有这个福利。究其原因,ES6 Module 是静态引用,在编译时即可确定依赖关系,而 commonJS 是动态引用。

不过使用 ES6 Module 时,ES6 的解构赋值语法这里有一个坑,例如 index.js 中有一行 import {fn, name} from './a.js' ,此时 a.js 中有以下几种写法,大家要注意!

正确写法:
// 正确写法一
export function fn() {
    console.log('fn')
}
export const name = 'b'

// 正确写法二
function fn() {
    console.log('fn')
}
const name = 'b'
export {
    fn,
    name
}
错误写法:
// 错误写法
function fn() {
    console.log('fn')
}
export default {
    fn,
    name: 'b'
}

本地服务dev

启动本地服务,肯定需要一个 html 页面作为载体,新建一个 src/index.html 并初始化内容
<!DOCTYPE html>
<html>
<head><title>Document</title></head>
<body>
    <p>this is index html</p>
</body>
</html>
但是为了使用html文件,还要安装 npm i html-webpack-plugin -D ,然后配置 build/webpack.common.js ,因为无论 dev 还是 prod 都需要打包 html 文件。
   plugins: [
        new HtmlWebpackPlugin({
            template: path.join(srcPath, 'index.html'),
            filename: 'index.html'
        })
    ]
此时就可以启动服务了
首先安装 npm i webpack-dev-server -D ,然后打开 build/webpack.dev.js配置serve。
只有运行代码才需要本地 server ,打包代码时不需要。
devServer: {
    port: 3000,
    progress: true,  // 显示打包的进度条
    contentBase: distPath,  // 根目录
    open: true,  // 自动打开浏览器
    compress: true  // 启动 gzip 压缩
}

还需要打开package.json 修改 scripts ,增加 "dev": "webpack-dev-server --config build/webpack.dev.js"

解决跨域

实际开发中,server 端提供的端口地址和前端可能不同,导致 ajax 收到跨域限制。使用 webpack-dev-server 可配置代理,解决跨域问题。如有需要,在 build/webpack.dev.js 中增加如下配置:
   devServer: {
        // 设置代理
        proxy: {
            // 将本地 /api/xxx 代理到 localhost:3000/api/xxx
            '/api': 'http://localhost:3000',

            // 将本地 /api2/xxx 代理到 localhost:3000/xxx
            '/api2': {
                target: 'http://localhost:3000',
                pathRewrite: {
                    '/api2': ''
                }
            }
        }

处理ES6

babel

由于现在浏览器还不能保证完全支持 ES6 ,将 ES6 编译为 ES5 ,需要借助 babel 这个神器。
安装 babel npm i babel-loader @babel/core @babel/preset-env -D ,然后修改 build/webpack.common.js 配置
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: ['babel-loader'],
                include: srcPath,
                exclude: /node_modules/
            },
        ]
    },
还要根目录下新建一个 .babelrc json 文件,内容如下:
{
    "presets": ["@babel/preset-env"],
    "plugins": []
}
配置完了会达到什么什么效果呢?
我们在 src/index.js 中加入一行 ES6 代码,如箭头函数 const fn = () => { console.log('this is fn') } 。
然后重新运行 npm run dev,可以看到浏览器中加载的 js 中,这个函数已经被编译为 function 形式。

使用高级特性
babel 可以解析 ES6 大部分语法特性,但是无法解析 class 、静态属性、块级作用域,还有很多大于 ES6 版本的语法特性,如装饰器。因此,想要把日常开发中的 ES6 代码全部转换为 ES5 ,还需要借助很多 babel 插件。

安装 npm i @babel/plugin-proposal-class-properties @babel/plugin-transform-block-scoping @babel/plugin-transform-classes -D ,然后配置 .babelrc
{
    "presets": ["@babel/preset-env"],
    "plugins": [
        "@babel/plugin-proposal-class-properties",
        "@babel/plugin-transform-block-scoping",
        "@babel/plugin-transform-classes"
    ]
}


Source map
source map 用于反解析压缩代码中错误的行列信息,
但dev 时代码没有压缩,用不到 source map ,因此要配置在build/webpack.prod.js
// webpack 中 source map 的可选项,是情况选择一种:

// devtool: 'source-map'  
// 1. 生成独立的 source map 文件
// devtool: 'eval-source-map'  
// 2. 同 1 ,但不会产生独立的文件,而是集成到打包出来的 js 文件中
// devtool: 'cheap-module-source-map'  
// 3. 生成单独的 source map 文件,但没有列信息(因此文件体积较小)
devtool: 'cheap-module-eval-source-map'  
// 4. 同 3 ,但不会产生独立的文件,集成到打包出来的 js 文件中
生产环境下推荐使用 1 或者 3 ,即生成独立的 map 文件。

处理样式
在 webpack 看来,不仅仅是 js ,其他的文件也是一个一个的模块,通过相应的 loader 进行解析并最终产出。
处理css
安装必要插件 npm i style-loader css-loader -D ,然后配置 build/webpack.common.js
    module: {
        rules: [
            { /* js loader */ },
            {
                test: /\.css$/,
                loader: ['style-loader', 'css-loader']  
                // loader 的执行顺序是:从后往前
            }
        ]
    },
处理less
安装必要插件 npm i less less-loader -D ,然后配置 build/webpack.common.js
            {
                test: /\.less$/,
                loader: ['style-loader', 'css-loader', 'less-loader'] 
                // 增加 'less-loader' ,注意顺序
            }






作者:双越
链接:https://www.imooc.com/article/287156
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作


作者:双越
链接:https://www.imooc.com/article/287156
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作



作者:双越
链接:https://www.imooc.com/article/287156
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作

作者:双越
链接:https://www.imooc.com/article/287156
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作




来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作





全部评论

相关推荐

07-23 15:05
门头沟学院 Java
熊大不大:不好意思KPI数据刚刚刷新,刚刚达标
点赞 评论 收藏
分享
7月12日投的,咋一点反馈都没有
投递禾赛科技等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务