美文网首页
react-01-webpack

react-01-webpack

作者: 未来在奋斗 | 来源:发表于2019-12-16 10:08 被阅读0次

    什么是webpack?

    问题:为什么在 vue 中使用 npm run build 命令就可以把开发环境中的文件进行合并?

    答案:无论是 vue 还是 react、angular,使用 cli 创建出来的项目,都自动的把结构做好了,内部的 webpack 也都配置好了,项目开发完毕后,只需要执行 build 命令,就能够把 src 下的文件进行打包,这个打包功能都是由 webpack 完成的,这个配置无需我们自己操作,vue、react、angular 内部已经整合完毕,只需要直接使用命令即可。

    如果想手动的一步一步的配置 webpack,那么可以根据下面的文档进行操作。

    webpack是资源加载/打包工具

    project1/
        src/
        dist/
    

    说白了,就是把开发环境src目录中的文件,打包到生产环境dist目录下。

    打包指把src下那些碎片化的文件,合并到一起,生成到dist下。

    部署指把dist目录当成网站根目录,供别人访问。

    如何使用webpack?

    全局安装

    npm i -g webpack webpack-cli
    

    查看版本号

    webpack -v      # 4.29.6
    webpack-cli -v  # 3.3.0
    

    创建项目目录

    mkdir project1 && cd project1
    

    初始化项目

    npm init
    

    npm init -y (-y参数的作用是创建package.json时都安装默认的来)

    局部安装

    npm i -D webpack webpack-cli
    

    创建目录结构、文件和内容:

    project1/
        package.json
        src/
            index.js
    

    src/index.js 中的代码:

    • 在安装一个要打包到生产环境的安装包时,应使用 npm i -S,完整写法为 npm install --save lodash
    • 如果安装一个用于开发环境的安装包,应使用 npm i -D,完整写法为 npm install --save-dev lodash
    // lodash 是一个js工具库,用来操作 object、array、number... 更方便了
    import _ from 'lodash'; // npm install --save lodash
    function component(){
        var element = document.createElement('div')
        element.innerHTML = _.join(['Hello', 'webpack'], ' ')
        return element; 
    }
    document.body.appendChild( component() )
    

    创建目录结构、文件和内容:

    project1/
        package.json
        dist/
            index.html
    

    dist/index.html 中的代码:

    • main.js 文件目前还不存在
    • 需要通过webpack把src/index.js文件及其依赖文件lodash打包到一起
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        
    </body>
    </html>        
    <script src="main.js"></script>
    

    在命令行中执行:

    npx webpack
    

    执行 npx webpack,会将我们的脚本作为入口起点,然后输出为 main.js

    Node 8.2+ 提供了 npx 命令,可以运行在初始安装的 webpack包(package)的webpack二进制文件

    然后就可以浏览dist/index.html网页了

    配置文件

    在项目根目录下建立webpack.config.js文件

    project1/
        webpack.config.js
    

    编写代码,配置打包内容。

    // 在 webpack 中使用 require 引入自带的path模块 (CommomJS规范)
    const path = require('path')
    module.exports = {
        entry: './src/index.js',
        output: {
            filename: 'index.js',
            path: path.resolve(__dirname, 'dist')
        }
    }
    

    entry描述的是入口;output描述的是出口。

    命令行执行:

    npx webpack --config webpack.config.js
    

    说明:根据配置页进行打包,入口为src/index.js,根据入口页的相关依赖,合并到dist/index.js中。

    也可以直接执行:

    webpack
    

    两个命令是等效的

    NPM脚本

    考虑到用 CLI 这种方法来运行本地的 webpack 不是特别方便,我们可以设置快捷方式。

    在 package.json 文件的 scripts 对象中,增加 build 脚本,当执行 build 脚本时,实际执行的是 webpack 命令。

    "scripts":{
        "abc" : "npx webpack --config webpack.config.js",
        "build": "webpack"
    }
    

    使用 npm run build 命令,代替之前使用的 webpack 命令。

    npm run build   # npm run abc
    

    资源管理

    加载当前项目所用到的其他资源

    • 加载 CSS
    • 加载图片
    • 加载字体

    加载 CSS

    下载在js中解析css的模块,我们要把js和css打包到一起。

    npm install -D style-loader css-loader
    

    webpack.config.js 配置规则

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

    module.rules表示使用webpack打包模块时所定义的打包规则。

    webpack打包时,如果碰到的是.css结尾的文件,使用style-loader和css-loader处理。

    • style-loader:将 JS 字符串生成为 style 节点
    • css-loader:将 CSS 转换为 CommonJS 模块

    src/style.css

    .hello { color:red }
    

    src/index.js

    import './style.css'
    function component(){
        // ........
        element.classList.add('hello')
    }
    

    命令行中执行:

    npm run build
    

    如果想使用 scss 文件,需要安装

    npm config set sass-binary-site http://npm.taobao.org/mirrors/node-sass

    npm install sass-loader node-sass --save-dev
    

    然后规则中配置:

    { test:/\.scss$/, use:['style-loader', 'css-loader', 'sass-loader'] }
    

    加载图片

    CSS 和 JS 中的图片如何处理?

    需要安装:

    npm install --save-dev file-loader
    

    然后在 webpack.config.js 页面中配置规则:

    { test:/\.(png|svg|jpg|gif)$/, use:['file-loader'] }
    

    创建文件及编写代码

    src/
        images/
            1.jpg
            2.jpg
        index.js
            import img from './images/1.jpg'
            myImg = new Image();
            myImg.src = img;
            document.body.appendChild( myImg );
        style.scss
            background: url(images/2.jpg)
    

    命令行执行:

    npm run build
    

    两张图片会被复制到 dist 目录下面,网页能正常使用,如果想配置图片输出后的路径,可以:

    use:[{
        loader:'file-loader', 
        options:{
            name:'[name].[ext]', 
            outputPath:'images'
        }
    }]
    

    加载字体

    字体这种资源需要用到 file-loader 或 url-loader

    npm i -D url-loader 
    

    规则配置:(二选一)

    • file-loader会保存单独的字体文件
    { test: /\.(woff|woff2|eot|ttf|otf)$/, use: ['file-loader'] }
    
    • url-loader会和js合并到一起
    { test: /\.(woff|woff2|eot|ttf|otf)$/, use: ['url-loader'] }
    

    style.css 或 style.scss

    @font-face{
        font-family: abc;
        src: url(./fonts/经典毛笔字体.ttf) format("truetype");
    }
    div{ font-family:"abc" }
    

    命令行

    npm run build
    

    多入口多出口

    PC端项目中可能有很多个入口,比如 index.html,比如 main.html 等,浏览器中都可以直接访问。

    移动端项目SPA都是单页面应用,用一个入口就可以了,如果是传统的PC端,那么需要用到很多入口页面。

    dist/index.html

    <script src="index.js"></script>
    

    dist/main.html

    <script src="main.js"></script>
    

    在浏览器中分别访问这两个文件,这两个文件分别依赖的js文件,都是独立的,这就是多入口多出口。

    wepack.config.js

    entry:{
        index:'./src/index.js',
        main:'./src/main.js'
    },
    output:{
        filename:'[name].js',
        path:path.resolve(__dirname, 'dist')
    }
    

    entry描述的是入口,表示有两个入口 ,一个名字叫做index,一个名字叫做main。

    output描述的是出口,filename描述的是打包后文件的名字,[name]是关键字表示entry入口文件名,path表示合并后文件所在位置。

    命令行:

    npm run build
    

    就能够根据entry的配置打包出2个js文件了

    插件

    安装:

    npm install --save-dev html-webpack-plugin
    

    webpack.config.js

    const HtmlWebpackPlugin = require('html-webpack-plugin')
    entry: { ... },
    plugins: [ new HtmlWebpackPlugin({title:'标题栏内容'}) ],
    output: { ... }
    

    HtmlWebpackPlugin 的作用就是在 dist 目录下生成 index.html 文件,

    我们现在的项目中存在 dist/index.html 所以命令执行后,会将之前的文件覆盖了,

    如果项目中不存在 dist/index.html,那么 HtmlWebpackPlugin 也能够根据默认的配置把这个 index 文件创建出来。

    清理dist目录

    每次执行webpack编译时,最好先把之前的内容清理干净,然后重新生成。

    npm install clean-webpack-plugin --save-dev
    

    webpack.config.js

    const { CleanWebpackPlugin } = require('clean-webpack-plugin')
    plugins:[
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin...
    ]
    

    错误调试

    webpack 是把很多个文件捆绑到一起,那么如果有段代码出错了,怎么定位错误?

    src/print.js

    把 console.log 改为 console.error 模拟一个错误出来,执行 npm run build 重新生成捆绑后的文件,浏览器运行。

    浏览器的控制台中会报错,因为我们访问的是生产环境下的代码,所以报的是生产环境下的错误,所以不好定位错误。

    webpack.config.js

    entry:{ ... },
    devtool: 'inline-source-map'
    

    加上 devtool 配置后,就能够定位到错误了,但要记得这仅仅是为了调试,生产时要关闭。

    自动编译和自动刷新

    每次修改文件后,都需要手动 npm run build 这太麻烦了,所以可以安装

    npm install --save-dev webpack-dev-server
    

    webpack.config.js

    devtool: 'inline-source-amp',
    devServer: { contentBase: './dist' }
    

    package.json

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

    命令行运行

    npm start
    

    然后直接修改 src 下的文件,在浏览器中浏览 dist 下的文件,看效果。

    别名

    可以把长的文件名配置短的别名,这样描述依赖文件时会方便一些。

    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    resolve:{
        alias: {
          '@': path.resolve('src'),
          '#': path.resolve('src/images'),
          'fa': path.resolve('src/fonts/font-awesome-4.7.0/css'),
        }
    },
    

    使用别名

    import printMe from '@/print.js'
    import img from '#/1.jpg';
    import 'fa/font-awesome.min.css'
    

    不能用$当别名,修改webpack.config.js后要重新npm start

    代理

    解决跨域问题的一种方案

    devServer: { 
        contentBase: './dist',
        proxy:{
            "/api": {
                target: "https://api.wyyijiaqin.com",
                pathRewrite: { '^/api': '' },
                //secure: false,
                changeOrigin: true,
            }
        } 
    },
    

    启动 devServer ,该代理才有作用。

    打包时,代码是否压缩?

    mode属性可以定义打包时代码是否压缩。

    • development 不压缩代码
    • production 压缩代码,默认
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    mode: "development"
    

    post-css

    cnpm i postcss-loader -D
    cnpm i autoprefixer -D  # 处理css浏览器兼容
    

    这个模块是用来处理css兼容的,会自动给css加上浏览器前缀,如-ms- -webkit- 等

    style/index.css

    span{
        background: red;
        color:white;
        display: flex;
        flex: 1;
        transform: translate(-50%, -50%)
    }
    

    index.js

    import './style/index.css';
    

    webpack.config.js

    {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', {
            loader: 'postcss-loader',
            options:{
                plugins: [
                    require('autoprefixer')("last 100 versions")
                ]
            }
        }]
    }
    

    require('autoprefixer')("last 100 versions") 参数改了就会出错。

    语义:如果碰到css文件,先用style-loader和css-loader 处理,然后用postcss-loader处理,使用require引入autoprefixer模块,处理css兼容

    多个 config 文件入口

    配置独立的 config 文件

    比如我希望开发环境中,使用map,即出错时,能够看到错误内容,而生产环境下,出错时,不希望看到出错的具体内容,而且生产环境下的map还影响了文件的体积,所以应该去掉。

    npm install --save-dev webpack-merge
    

    通用配置 common.js

    const path = require('path');
    
    module.exports = {
        entry: {
            index: './src/index.js'
        },
        output: {
            filename: '[name].js',
            path: path.resolve(__dirname, 'dist')
        }
    };
    

    开发环境的配置 dev.js

    const merge = require('webpack-merge');
    const common = require('./common.js');
    
    module.exports = merge(common, {
        devtool: 'inline-source-map',
        devServer: {
            contentBase: './dist'
        }
    });
    

    生产环境的配置 prod.js

    const merge = require('webpack-merge');
    const common = require('./common.js');
    
    module.exports = merge(common, {
    
    });
    

    package.json

    "scripts": {
        "start": "webpack-dev-server --open --config dev.js",
        "build": "webpack --config prod.js"
    }
    

    执行 npm start 相当于开启了开发环境的服务,如果出错了,检查是不是某类文件类型的合并规则没有被定义。

    执行 npm run build 表示根据开发环境中的文件,合并成生产环境下的文件。

    相关文章

      网友评论

          本文标题:react-01-webpack

          本文链接:https://www.haomeiwen.com/subject/ecsdnctx.html