webpack做文件合并

使用构建工具非常常用一个功能就是合并js和css文件,gulp和grunt都是编写相应的任务来完成,转到webpack突然懵逼了,简单的项目怎么做文件合并呢?其实只需把多个js文件同时引入到main.js(入口文件)中即可,css借助extract-text-webpack-plugin搞定。

不管是简单的纯展示页面还是复杂的单页或多页面,webpack差不多可以彻底取代gulp、grunt了,利用file、scss、pug、babel等各种loader处理各种需求比grunt那种编写任务型的配置方便太多。

webpack非常智能,多次引入相同模块,最终打包后只会包含一次。如果你不想打包某个模块,在webpack.config.js里配置externals即可。对于css模块,externals是无效的,js里不引入,直接在html里放link就好了,不要陷入webpack的魔障。对于一些老旧的jq插件,可以配置providePlugin或使用expose-loader,用法就自行google了。熟悉了之后,各种新旧项目,大小项目都能用webpack耍的飞起。

// webpack.config.js
// ...

externals: {
    'vue': 'Vue','jquery': 'jQuery',},

webpack-dev-server跨域设置

开发的时候经常有跨域需求,前端跨域方法虽然很多,但是只是为了开发时用用,感觉没一个好用的。利用webpack-dev-server可以轻松解决开发时跨域问题,devServer启动了一个node服务器帮你代理请求,详细配置请看proxy,这个设置是将所有以/api开头的路由映射到xxx.com,target记得带上协议名哦(http://)。pathRewrite就是将/api/a路径重写为/a。当然你也可以配置为/转发请求,这样静态资源也可以在localhost下请求到了。跨域的前提是服务器上配置了'Access-Control-Allow-Origin:*',开发时服务器端一般都设置了。

// webpack.config.js
// ...

devServer: {
    port: 8888,historyApiFallback: true,stats: 'minimal',// 输入精简信息
    overlay: true,// 将错误显示在html之上
    proxy: {
        '/api': {
            target: 'http://xxx.com',secure: false,changeOrigin: true,// pathRewrite: {'^/api': ''},}
    }
},

webpack-dev-server热更新失效

自从用了webpack-dev-server,我的f5键长舒一口气,不过有时候碰到webpack-dev-server热更新回失效,一般是配置出了问题。只需在pulugins里添加HotModule插件,devServer不要配置hot:true了,虽然文档里写的是设置hot:true开启热更新,但是我试过配置hot热更新就失效了,不解!

// webpack.config.js
// ...

plugins: [
        new webpack.HotModuleReplacementPlugin(),// 热加载
]

使用pug(jade)作为vue文件中的html模板

npm安装pug,记住不是pug-loader,也不用配置vue-loader,只需在template标签中指定lang=pug,就可以愉快的使用pug语法了,比起html看起来简洁多了。

<template lang="pug">
    header
        .logo
        h1 我是头部
</template>

html-webpack-plugin在多页面中的妙用

以前只用webpack写单页引用,index.html就是个空壳,后来也有一些纯展示页面,包含多个html文件,也想用webpack,毕竟各种loader太好用了。这时候就需要好好利用html-webpack-plugin了。直接上一个webpack配置,基于vue-simple的webpack配置做了些修改,同时参考了歪闹大神的webpack多页面教程,利用glod获取文件名,自动生成html-webpack-plugin配置,so geek!利用pug写html,scss写css,作为一个页面仔,也不那么无聊了,效率也是杠杠滴。

let path = require('path');
let webpack = require('webpack');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let glob = require('glob');

// js名必须与html的fileName对应
let entry = (() => {
    let obj = {};
    getEntry('src/views/pages/*.pug').forEach(fileName => {
        obj[fileName] = './src/js/' + fileName + '.js';
    });
    return obj;
})();

module.exports = {
    entry: entry,output: {
        path: path.resolve(__dirname,'./dist'),publicPath: '/dist/',filename: 'js/[name].js',// chunkFilename: 'js/[name][id].chunk.js',// 公共代码块
    },externals: {
        // 'vue': 'Vue',// 'jquery': 'jQuery',module: {
        rules: [
            {
                test: /\.vue$/,loader: 'vue-loader',options: {
                    loaders: {
                        scss: ExtractTextPlugin.extract({
                            fallback: 'vue-style-loader',use: 'css-loader!sass-loader',}),}
                }
            },{
                test: /\.js$/,loader: 'babel-loader',exclude: /node_modules/
            },// 不要使用options配置url-loader webpack会报错
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url-loader?limit=10000&name=img/[name].[hash:7].[ext]',{
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,loader: 'file-loader?limit=10000&name=img/[name].[hash:7].[ext]',{
                test: /\.scss$/,loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',use: 'css-loader!postcss-loader!sass-loader'
                })
            },{
                test: /\.css$/,use: 'css-loader!postcss-loader'
                })
            },{
                test: /\.html$/,loader: 'html-loader?attrs=img:src img:data-src'
            },{
                test: /\.pug$/,loader: 'pug-loader'
            },]
    },resolve: {
        extensions: ['.js','.vue','.json'],alias: {}
    },devServer: {
        port: 8888,// 输入精简信息
        overlay: true,// 将错误显示在html之上
        proxy: {
            '/api': {
                target: 'http://localhost:9999',}
        }
    },performance: {
        hints: false
    },devtool: '#eval-source-map',plugins: [
        new webpack.HotModuleReplacementPlugin(),// 热加载

        // new webpack.ProvidePlugin({
        //     $: 'jquery',//     jQuery: 'jquery',// }),new ExtractTextPlugin('css/[name].css'),//单独使用link标签加载css并设置路径,相对于output配置中的publicPath

    ],};

if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = '#source-map';
    // http://vue-loader.vuejs.org/en/workflow/production.html
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),new webpack.optimize.UglifyJsPlugin({
            sourceMap: true,compress: {
                warnings: false
            }
        }),new webpack.LoaderOptionsPlugin({
            minimize: true
        })
    ]);
}

// 自动生htmlPlugins
getEntry('src/views/pages/*.pug').forEach(fileName => {
    let conf = {
        filename: fileName + '.html',//生成的html存放路径,相对于path
        template: 'src/views/pages/' + fileName + '.pug',//html模板路径
        inject: true,hash: true,minify: {
            removeComments: true,minifyJS: true,chunks: [fileName],};
    module.exports.plugins.push(new HtmlWebpackPlugin(conf));
});

// 获取文件名函数
function getEntry(viewsPath) {
    let files = glob.sync(viewsPath);
    let entries = [];
    let entry,basename,extname;

    for (let i = 0; i < files.length; i++) {
        entry = files[i];
        extname = path.extname(entry); // 扩展名 eg: .html
        basename = path.basename(entry,extname);  // eg: index
        entries.push(basename);
    }
    return entries;
}

npm pakeage也贴一下吧

{
  "name": "vue-admin-front-end","description": "vue-admin","version": "0.0.1","author": "win5do <win5do@qq.com>","private": true,"scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --colors","build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
  },"dependencies": {
    "animate.css": "^3.5.2","axios": "^0.16.1","element-ui": "^1.2.9","minireset.css": "^0.0.3","vue": "^2.2.6","vue-router": "^2.5.2","vueditor": "^0.2.4","vuex": "^2.3.1"
  },"devDependencies": {
    "babel-core": "^6.24.1","babel-loader": "^7.0.0","babel-preset-latest": "^6.24.1","cross-env": "^4.0.0","css-loader": "^0.28.0","element-theme-default": "^1.2.9","expose-loader": "^0.7.3","extract-text-webpack-plugin": "^2.1.0","file-loader": "^0.11.1","glob": "^7.1.1","html-loader": "^0.4.5","html-webpack-plugin": "^2.28.0","node-sass": "^4.5.2","postcss-loader": "^1.3.3","pug": "^2.0.0-beta.12","pug-loader": "^2.3.0","sass-loader": "^6.0.3","style-loader": "^0.16.1","url-loader": "^0.5.8","vue-loader": "^11.3.4","vue-template-compiler": "^2.2.6","webpack": "^2.4.1","webpack-dev-server": "^2.4.4"
  }
}

webpack在前端项目中使用心得一二的更多相关文章

  1. HTML实现代码雨源码及效果示例

    这篇文章主要介绍了HTML实现代码雨源码及效果示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. css绝对定位如何在不同分辨率下的电脑正常显示定位位置?(一定要看!)

    这篇文章主要介绍了css绝对定位如何在不同分辨率下的电脑正常显示定位位置,本文首先解释了常见的电脑分辨率,为了页面在不同的分辨率下正常显示,要给页面一个安全宽度,再去使用绝对定位,具体操作步骤大家可查看下文的详细讲解,感兴趣的小伙伴们可以参考一下。

  3. 详解HTML5中CSS外观属性

    这篇文章主要介绍了HTML5中CSS外观属性的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,,需要的朋友可以参考下

  4. HTML文本属性&amp;颜色控制属性的实现

    这篇文章主要介绍了HTML文本属性&颜色控制属性的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. CSS中实现动画效果-附案例

    这篇文章主要介绍了 CSS中实现动画效果并附上案例代码及实现效果,就是CSS动画样式处理,动画声明需要使用@keyframes name,后面的name是人为定义的动画名称,下面我们来看看文章的具体实现内容吧,需要的小伙伴可以参考一下

  6. 简洁自适应404页面HTML好看的404源码

    这篇文章主要介绍了简洁自适应404页面HTML好看的404源码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  7. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. HTML5适合的情人节礼物有纪念日期功能

    这篇文章主要介绍了HTML5适合的情人节礼物有纪念日期功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. 如何给HTML标签中的文本设置修饰线

    这篇文章主要介绍了如何给HTML标签中的文本设置修饰线,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. Html5自定义字体解决方法

    这篇文章主要介绍了Html5自定义字体解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. xe-ajax-mock 前端虚拟服务

    最新版本见Github,点击查看历史版本基于XEAjax扩展的Mock虚拟服务插件;对于前后端分离的开发模式,ajax+mock使前端不再依赖后端接口开发效率更高。CDN使用script方式安装,XEAjaxMock会定义为全局变量生产环境请使用xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

  2. vue 使用 xe-ajax

    安装完成后自动挂载在vue实例this.$ajaxCDN安装使用script方式安装,VXEAjax会定义为全局变量生产环境请使用vxe-ajax.min.js,更小的压缩版本,可以带来更快的速度体验。cdnjs获取最新版本点击浏览已发布的所有npm包源码unpkg获取最新版本点击浏览已发布的所有npm包源码AMD安装require.js安装示例ES6Module安装通过Vue.use()来全局安装示例./Home.vue

  3. AJAX POST数据中文乱码解决

    前端使用encodeURI进行编码后台java.net.URLDecoder进行解码编解码工具

  4. Koa2框架利用CORS完成跨域ajax请求

    实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明。这样OPTIONS请求就能够通过了。至此为止,相当于仅仅完成了预检,还没发送真正的请求呢。

  5. form提交时,ajax上传文件并更新到&lt;input&gt;中的value字段

  6. ajax的cache作用

    filePath="+escape;},error:{alert;}});解决方案:1.加cache:false2.url加随机数正常代码:网上高人解读:cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。

  7. 浅谈ajax上传文件属性contentType = false

    默认值为contentType="application/x-www-form-urlencoded".在默认情况下,内容编码类型满足大多数情况。在这里,我们主要谈谈contentType=false.在使用ajax上传文件时:在其中先封装了一个formData对象,然后使用post方法将文件传给服务器。说到这,我们发现在JQueryajax()方法中我们使contentType=false,这不是冲突了吗?这就是因为当我们在form标签中设置了enctype=“multipart/form-data”,

  8. 909422229_ajaxFileUpload上传文件

    ajaxFileUpload.js很多同名的,因为做出来一个很容易。我上github搜AjaxFileUpload出来很多类似js。ajaxFileUpload是一个异步上传文件的jQuery插件传一个不知道什么版本的上来,以后不用到处找了。语法:$.ajaxFileUploadoptions参数说明:1、url上传处理程序地址。2,fileElementId需要上传的文件域的ID,即的ID。3,secureuri是否启用安全提交,默认为false。4,dataType服务器返回的数据类型。6,error

  9. AJAX-Cache:一款好用的Ajax缓存插件

    原文链接AJAX-Cache是什么Ajax是前端开发必不可少的数据获取手段,在频繁的异步请求业务中,我们往往需要利用“缓存”提升界面响应速度,减少网络资源占用。AJAX-Cache是一款jQuery缓存插件,可以为$.ajax()方法扩展缓存功能。

  10. jsf – Ajax update/render在已渲染属性的组件上不起作用

    我试图ajax更新一个有条件渲染的组件。我可以确保#{user}实际上是可用的。这是怎么引起的,我该如何解决呢?必须始终在ajax可以重新呈现之前呈现组件。Ajax正在使用JavaScriptdocument.getElementById()来查找需要更新的组件。但是如果JSF没有将组件放在第一位,那么JavaScript找不到要更新的内容。解决方案是简单地引用总是渲染的父组件。

返回
顶部