webpack总结 & 个人理解

作者: ccminn | 来源:发表于2017-07-13 11:03 被阅读89次

    目录:

    1. 学习资源
    2. 概念总结
    3. webpack必要元素
    4. webpack其他元素
    5. 遇到的问题
    6. 常见loader整理
    7. 常见plugin整理
    8. devServer扩展阅读

    1. 学习资源

    maximilian 教学视频
    webpack2 中文文档

    2. 概念性总结

    学习总结

    由于个人对于抽象概念的理解能力较差,刚开始阅读文档进度很慢,而且看下来的效果并不好;
    通过观看教学视频,感觉才是真正的体会到了webpack的实际用途,从实际用途出发再去理解文档就显得轻松一些;
    虽然笔记写了一大篇,实际运用还是有不少坑,零碎的知识点也不少... 继续实践继续总结....

    一句话总结时间:

    将entry文件涉及到的所有js、css、less、img等(一条引用链),打包为一个独立js,能够替代以上所有的文件。

    如何形成一条完整引用链:

    原本的css在html中使用link标签引用;现改为在js中import './xxx.css'
    如果多个css之间关联使用(如scss),可以在css内部形成一条引用链,即在css中 import './xxx.css',再在js中引用这个处在css引用链末端的css

    bundle.js的用处:

    生成的bundle.js可以替代entry中对应源的所有涉及文件资源;
    实际表现为,原先所有的html中的引用(link与script标签),都可以用引入bundle.js来替代

    打包命令:

    webpack 根据webpack.config.js生成打包文件
    webpack -p 根据webpack.config.js生成打包文件,并且把打包文件压缩
    webpack-dev-server 在服务器上运行webpack打包后的项目,打包文件只出现在服务器上,不出现在项目实体中

    3. 必要要素:

    • entry
    • output
    • loader
    • plugins [array]
    // 基本模板
    var path = require("path");     // 路径解析package
    
    // require获取、配置第三方插件
    var extractTextPlugin = require("extract-text-webpack-plugin"); 
    var extractPlugin = new extractTextPlugin({
        filename:'main.css'
    });
    var htmlWebpackPlugin = require('html-webpack-plugin');
    var cleanPlugin = require('clean-webpack-plugin');
    
    // 引入webpack-package,使用其中的插件
    var webpack = require('webpack');    
    
    // 以module的形式输出
    module.exports = {
    
        entry: {
            bundle: './src/js/app.js'   // webpack的入口文件,将app中所有使用到的引用以及语法特性等能够打包的内容全部打包;  
        },
    
        output: {
            path: path.resolve(__dirname, "dist"),
            filename: 'bundle.js'  // entry文件的打包最终成果的文件名
            publicPath: '/dist'    // 此属性用于在webpack-dev-server部署到服务器时候,告诉服务器该去哪里查找(查找webpack生成在服务器端的打包文件)
        },
    
        module: {
            //  rules以数组属性,配置不同文件的打包规则
            rules: [
                {
                    test: /\.js$/,   // 匹配原则,正则表达式:以.js结尾
                    // 当use中出现多个loader,加载顺序从后往前,比如打包css文件时,写作:['style-loader','css-loader'],先用css-loader载入css文件,再使用style-loader把样式style引入待打包的js文件
                    use: [
                        {
                            loader: 'babel-loader',
                            // option类似于一个get路径中的queryString,用于配置loader,可以写作字符串形式
                            options: {
                                presets: ['es2015']
                            }
                        }
                    ]
                } 
            ]
        },
    
        plugins: [
            // extractPlugin 指定inject位置
            extractPlugin, 
            // DefinePlugin: 暴露全局变量
            new webpack.DefinePlugin({
              PRODUCTION: JSON.stringify("production")  
            })
            // ProvidePlugin:解析符号定义
            new webpack.ProvidePlugin({
               $: 'jquery',       // 告诉解析器,遇到这个符号,就去找package
            }),
            // htmlWebpackPlugin插件: 用于复制html,并且向其中自动注入(inject)服务器端生成的js等文件
            new htmlWebpackPlugin({
              filename: 'index.html',
              template: 'src/index.html'
            }),
            // cleanPlugin用于:每次使用webpack生成打包文件前先抹除dist文件下的旧打包文件
            new cleanPlugin(['dist'])   
        ]
    }
    

    4. 其他属性

    module.exports = {
        // devServer: 用于配置webpack-dev-server命令启动的服务器
        devServer: {
            // publicPath: 此路径下的打包文件在浏览器中可访问;也是打包文件的存放目录,必须保证"/"开头、结尾
            publicPath: /asset/   // 确定应该从哪里提取bundle,优先于contentBase属性
            contentBase: path.join(__dirname, "dist"),   // 告诉服务器从哪里提供(静态)内容
            compress: true,   // 一切服务都启用gzip压缩
            port: 9000       //  指定监听请求的端口号
            headers: {"X-Custom-Foo": "bar"}   // 在所有请求中添加首部内容
            historyApiFallback: true   // 任意404相应提供为index.html 
            host: "0.0.0.0"  // 指定使用一个host  默认是localhost
            hot: true    // 热加载
            lazy: true  // 惰性模式:只在请求时,才编译bundle(不watch文件变动) 
            proxy: {
                "/api": "http://localhost:3000",  // 向后端服务器3030发送api请求
                // 对当前服务器/api/users的请求,现在会被代理到http://localhost:3000/api/users
                pathRewrite: {"^/api" : ""},   // 重写路径:可以停止传递
                secure: false,    // 默认不接受https上的使用无效证书的后端服务器;set false则接受所有
                bypass: function(){}   // 对路由进行处理,在不停用代理的情况下绕过代理
            }
    
        watch: true,   // watch属性监测文件改动,默认false
    
        devtool: 'source-map',   // 当js使用了uglify插件进行压缩,debug时无法一一对应,因此使用source-map建立映射
    
    
    }
    

    5. 遇到的问题

    1、 图片打包路径引用问题

    引用webpack打包的图片,引用路径错误
    错误原因: 对于原始图片,使用了相对路径进行引用

    解决方法1:

    源码图片路径和打包后的图片路径保持一致,比如:源码图片是放在/src/img/a.png下,引用图片的的css路径是/src/style/a.css, 这时候a.css的引用写法是 url("../img/a.png");打包后的图片路径是放在/build/img/a.png,引用图片的的css路径是/build/style/a.css, 这时候a.css的引用写法还是 url("../img/a.png"),这时候就不会出问题

    解决方法2:

    webpack.config.js使用绝对路径publicPath:
    如果是放在dist目录下:

    output: {
            publicPath:'/dist/'
    }
    

    这样所有资源文件的路径都会把publicPath放到前面,就不会有路径问题了

    6. loader整理

    • less-loader 引入less文件
    • css-loader 引入css文件
    • style-loader 引入样式
    • bable-core 转换es6
    • babel-loader 引入转换后的js
    • html-loader 转换html的import

    7. 插件整理

    • html-webpack-plugin 重建html,包含webpack打包后的正确引用inject
    • clean-webpack-plugin 清除历史build文件(dist)后再重新打包
    • extract-text-webpack-plugin 分离css文件
    • CommonsChunkPlugin 公共模块提取单独打包
    • uglifyjs-webpack-plugin 压缩js文件

    8. devServer配置扩展阅读

    devServer: {
      // webpack-dev-server options
    
      contentBase: "/path/to/directory",
      // Can also be an array, or: contentBase: "http://localhost/",
    
      hot: true,
      // Enable special support for Hot Module Replacement
      // Page is no longer updated, but a "webpackHotUpdate" message is sent to the content
      // Use "webpack/hot/dev-server" as additional module in your entry point
      // Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does. 
    
      historyApiFallback: false,
      // Set this as true if you want to access dev server from arbitrary url.
      // This is handy if you are using a html5 router.
    
      compress: true,
      // Set this if you want to enable gzip compression for assets
    
      proxy: {
        "**": "http://localhost:9090"
      },
      // Set this if you want webpack-dev-server to delegate a single path to an arbitrary server.
      // Use "**" to proxy all paths to the specified server.
      // This is useful if you want to get rid of 'http://localhost:8080/' in script[src],
      // and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ).
    
      setup: function(app) {
        // Here you can access the Express app object and add your own custom middleware to it.
        // For example, to define custom handlers for some paths:
        // app.get('/some/path', function(req, res) {
        //   res.json({ custom: 'response' });
        // });
      },
    
      // pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server
      staticOptions: {
      },
    
      clientLogLevel: "info",
      // Control the console log messages shown in the browser when using inline mode. Can be `error`, `warning`, `info` or `none`.
    
      // webpack-dev-middleware options
      quiet: false,
      noInfo: false,
      lazy: true,
      filename: "bundle.js",
      watchOptions: {
        aggregateTimeout: 300,
        poll: 1000
      },
      // It's a required option.
      publicPath: "/assets/",
      headers: { "X-Custom-Header": "yes" },
      stats: { colors: true },
    
      https: {
        cert: fs.readFileSync("path-to-cert-file.pem"),
        key: fs.readFileSync("path-to-key-file.pem"),
        cacert: fs.readFileSync("path-to-cacert-file.pem")
      }
    });
    
    

    相关文章

      网友评论

        本文标题:webpack总结 & 个人理解

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