webpack-best-practice-最好实践-布置临盆

tip

webpack的入门篇能够看我的这一片博文。
《怎样运用webpack—webpack-howto》.

媒介

近来一段时间在项目中运用了webpack和React来开辟,总之来讲也是遇到了很多坑,webpack毕竟照样比较新的手艺,而且也很难有一个很好的构建案例来顺应一切的项目,总之,在看了很多项目demo和官方文档以及官方引荐的tutorials以后,也算是本身总结出的一套最好实践吧。

代码

代码能够在我的Github上。
能够戳这里~~

package.json 敕令设置

既然是须要用到的是现实项目的构建,那末必定就要斟酌开辟环境和临盆环境下的设置项了:

// package.json
{
  // ...
  "scripts": {
    "build": "webpack --progress --colors --watch",
    "watch": "webpack-dev-server --hot --progress --colors",
    "dist": "NODE_ENV=production webpack --progress --colors"
  },
  // ...
}

能够在目次下实行

npm run build
npm run watch
npm run dist

解释一下:

  • build 是在我们开辟环境下实行的构建敕令;

  • watch 也是在开辟环境下实行,然则加了webpack最壮大的功用--搭建静态服务器和热插拔功用(这个在背面引见;

  • dist 是项目在要布置到临盆环境时打包宣布。

dist 内里的NODE_ENV=production是声明了当前实行的环境是production-临盆环境

背面随着几个敕令:

  • –colors 输出的效果带彩色

  • –progress 输出进度显现

  • –watch 动态及时监测依靠文件变化而且更新

  • –hot 是热插拔

  • –display-error-details 毛病的时刻显现更多细致毛病信息

  • –display-modules 默许情况下 node_modules 下的模块会被隐蔽,加上这个参数能够显现这些被隐蔽的模块

  • -w 动态及时监测依靠文件变化而且更新

  • -d 供应sorcemap

  • -p 对打包文件举行紧缩

目次构造

如今前端模块化的趋向致使目次构造也发生了很大的转变和争议,这只是我本身用到的一种情势,能够参考。

.
├── app                 #开辟目次
|   ├──assets           #寄存静态资本
|   |   ├──datas        #寄存数据 json 文件
|   |   ├──images       #寄存图片资本文件
|   |   └──styles       #寄存全局sass变量文件和reset文件
|   ├──lib
|   |   ├──components   #寄存数据 模块组件 文件
|   |   |   └──Header
|   |   |       ├──Header.jsx
|   |   |       └──Header.scss
|   |   |       
|   |   └──utils        #寄存utils东西函数文件
|   |
|   └──views
|       ├──Index        #进口文件
|       |   ├──Index.html #html文件
|       |   ├──Index.jsx
|       |   └──Index.scss
|       └──Index2
├── dist                #宣布目次
├── node_modules        #包文件夹
├── .gitignore     
├── .jshintrc      
├── webpack.config.js   #webpack设置文件
└── package.json

详细能够到Github上看demo。

webpack.config.js

引入包

var webpack = require('webpack');
var path = require('path');
var fs = require('fs');

这个毋庸置疑吧。

推断是不是是在当前临盆环境

定义函数推断是不是是在当前临盆环境,这个很主要,一名开辟环境和临盆环境设置上有一些区分

var isProduction = function () {
  return process.env.NODE_ENV === 'production';
};

声明文件夹

// 定义输出文件夹
var outputDir = './dist';
// 定义开辟文件夹
var entryPath = './app/views';

定义插件

var plugins = [
  new webpack.optimize.CommonsChunkPlugin({
    name: 'commons',
    filename: 'js/commons.js',
  }),
  new webpack.ProvidePlugin({
    React: 'react',
    ReactDOM: 'react-dom',
    reqwest: 'reqwest',
  }),
];
if( isProduction() ) {
  plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      test: /(\.jsx|\.js)$/,
      compress: {
        warnings: false
      },
    })
  );
}
  1. CommonsChunkPlugin 插件能够打包一切文件的共用部份临盆一个commons.js文件。

  2. ProvidePlugin 插件能够定义一个共用的进口,比方下面加的 React ,他会在每一个文件自动require了react,所以你在文件中不须要 require('react'),也能够运用 React。

  3. 假如是在临盆环境下,则到场插件 UglifyJsPlugin ,实行代码紧缩,而且去除 warnings。

自动遍历多文件进口

var entris = fs.readdirSync(entryPath).reduce(function (o, filename) {
    !/\./.test(filename) &&
    (o[filename] = './' + path.join(entryPath, filename, filename + '.jsx'));
    return o;
  }, {}
);

函数会自动遍历开辟的进口文件夹下面的文件,然后逐一临盆进口而且返回一个对象--进口。

假如在这一步不须要多页面多进口

那末能够运用html-webpack-plugin插件,它能够自动为进口天生一个html文件,设置以下:

var HtmlWebpackPlugin = require('html-webpack-plugin');
plugins.push(new HtmlWebpackPlugin({
  title: 'index',
  filename: outputDir+'/index.html',  #天生html的位置
  inject: 'body',                     #插进去script在body标签里
}));

entry 就能够自定义一个进口就够了

config的详细设置

var config = {
  target: 'web',
  cache: true,
  entry: entris,
  output: {
    path: outputDir,
    filename: 'js/[name].bundle.js',
    publicPath: isProduction()? 'http://******' : 'http://localhost:3000',
  },
  module: {
    loaders: [
      {
        test: /(\.jsx|\.js)$/,
        loaders: ['babel?presets[]=es2015&presets[]=react'],
        exclude: /node_modules/
      },
      {
        test: /\.scss$/,
        loaders: ['style', 'css?root='+__dirname, 'resolve-url', 'sass']
      },
      {
        test: /\.json$/,
        loader: 'json',
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/,
        loader: 'url?limit=1024&name=img/[name].[ext]'
      },
      {
        test: /\.(woff2?|otf|eot|svg|ttf)$/i,
        loader: 'url?name=fonts/[name].[ext]'
      },
      {
        test: /\.html$/,
        loader: 'file?name=views/[name].[ext]'
      },
    ]
  },
  plugins: plugins,
  resolve: {
    extensions: ['', '.js', 'jsx'],
  },
  devtool: isProduction()?null:'source-map',
};

这里来逐一申明:

关于output

path和filename都不必多说了,path是天生文件的寄存目次,filename是文件名,固然能够在前面加上目次位置。
这里提示一下,filename 的相对途径就是 path了,而且下面 静态文件天生的filename也是相关于这里的path的,比方 image 和 html。
publicPath 的话是打包的时刻天生的文件链接,比方 图片 资本,
假如是在临盆环境固然是用服务器地点,假如是开辟环境就是用当地静态服务器的地点。

module loaders 打包加载的处置惩罚器

能够不必夹 loader了 比方 本来 url-loader 如今 url

js/jsx

{
  test: /(\.jsx|\.js)$/,
  loaders: ['babel?presets[]=es2015&presets[]=react'],
  exclude: /node_modules/
},

关于js文件和jsx文件用了babel来处置惩罚,这里注重一下,最新版本的babel吧es2015和react的处置惩罚分开了,一切要这么写。

处置惩罚scss文件

{
  test: /\.scss$/,
  loaders: ['style', 'css?root='+__dirname, 'resolve-url', 'sass']
},

这里用了sass、css、style的loader这不必多说了。
那末root和resolve-url是怎么回事呢,root是定义了scss文件内里声明的url地点是相关于根目次的,然后resolve-url归去相对剖析这个途径,而不必require去猎取,比方

background: url('./assets/images/webpack.png');

如许就能够加载到./assets/images/webpack.png这个文件,而不必运用相对途径和require

处置惩罚json文件

{
  test: /\.json$/,
  loader: 'json',
},

关于json文件,能够自动要求该模块而且打包。

处置惩罚 图片 字体 资本文件

{
  test: /\.(jpe?g|png|gif|svg)$/,
  loader: 'url?limit=1024&name=img/[name].[ext]'
},
{
  test: /\.(woff2?|otf|eot|svg|ttf)$/i,
  loader: 'url?name=fonts/[name].[ext]'
},

这里运用了 url 这个loader,然则url依靠 file-loader,它是对file-loader的二次封装。
在要求图片的时刻假如文件大小小于 1024k ,运用内联 base64 URLs,否则会自动导入到name所声明的目次,这里是相对之前声明的 outputDir 途径。
字体资本也是一样。

处置惩罚html文件

{
  test: /\.html$/,
  loader: 'file?name=views/[name].[ext]'
},

在多页面的项目中须要,能够自动吧html文件导入到指定的临盆文件夹下。

resolve

resolve: {
  extensions: ['', '.js', 'jsx'],
},

是能够疏忽的文件后缀名,比方能够直接require('Header');而不必加.jsx。

devtool

devtool: isProduction()?null:'source-map',

划定了在开辟环境下才运用 source-map。

疑问

目前为止,关于多页面项目照样没有找到一个很好的计划去构建自动化。

原文能够看我的博客 webpack-best-practice-最好实践-布置临盆;

    原文作者:阿城
    原文地址: https://segmentfault.com/a/1190000004104496
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞