2019-05-10

2019-05-10

[2019-05-25]vscode支持webpack alias resolver
[2019-05-24]vue-cli3.x 生成的项目, 在不同平台(mac & windows)下构建出来的代码 contenthash 不一致
[2019-05-22]可以使用微信小程序 Component 构造来生成 Page
[2019-05-19]mac 生成 pkcs12 格式 ssl 证书
[2019-05-18]webpack 指定多个静态文件夹
[2019-05-14]vue-cli 使用 npm script 指定配置文件路径, 在 windows 下不能正常识别
[2019-05-14]git 子模块相关命令
[2019-05-11]vue-cli3.x 脚手架生成的项目, vue.config.js 使用 pages 配置多页应用时, 无法指定 template loader
[2019-05-10]webpack 使用动态加载import()引入的 ES6 模块, 需要通过 default 属性才能获取到模块内容

[2019-05-25]vscode配置jsconfig.json支持webpack alias resolver

vscode官方文档有说明如何通过配置jsconfig.json来支持webpack路径别名

更方便的做法是只配置jsconfig.json, 然后再webpack配置中引入再去配置alias

// jsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"],
      "common/*": ["./src/common/*"]
    }
  }
}

// 以vue.config.js为例
const aliasPaths = require('jsconfig.json').compilerOptions.paths;

module.exports = {
  chainWebpack: config => {
    Object.keys(aliasPaths).forEach(k => {
      let v = aliasPaths[k][0];
      v = v.substring(0, v.length - 2);
      k = k.split('/')[0];
      config.resolve.alias.set(k, path.resolve(__dirname, v));
    }
  }
}

需要注意, 配置jsconfig之后有路径输入智能提示的也只有js文件

[2019-05-24]vue-cli3.x 生成的项目, 在不同平台下构建出来的代码 contenthash 不一致

问题定位

  1. 删除所有依赖, 仅留下入口文件, 发现 contenthash 还是不一样
  2. 使用prettier-webpack-plugin在构建前对代码进行格式化, 避免因为换行符等问题导致文件内容不一致, 结果出来 contenthash 还是不一样
  3. 查看 hash 计算前的文件内容(可参看这里, 发现引入 polyfill 的时候使用了绝对路径, 确认是@vue/babel-preset-app的问题
  4. 找到相关 issuevue-cli#2807, 可以修改 babel 配置, 并删除 node_modules 缓存即可, 注意需要把@vue/babel-preset-app依赖升级到3.7.0
rm -rf node_modules/.cache
module.exports = {
  presets: [["@vue/app", { absoluteRuntime: false }]]
};

按上面的步骤处理之后, 在同一台mac不同路径不同的mac下构建出来的 contenthash 就会一直

但是发现 windows 的构建结果依然会 mac 下不一致

未完待续…

相关资料

https://github.com/webpack/webpack/issues/2215 https://medium.com/@the_teacher/webpack-different-assets-hashes-on-different-machines-the-problem-the-solution-ec6383983b99 https://github.com/vuejs/vue-cli/issues/2807

[2019-05-22]可以使用微信小程序 Component 构造来生成 Page

小程序官方文档有相关说明

事实上,小程序的页面也可以视为自定义组件。因而,页面也可以使用 Component 构造器构造,拥有与普通组件一样的定义段与实例方法。但此时要求对应 json 文件中包含 usingComponents 定义段。

而如果想使用小程序自定义组件测试工具集来对Page进行单元测试的话

可以参考miniprogram-simulate#7这条 issue

[2019-05-19]mac 生成 pkcs12 ssl 证书
openssl genrsa -out key.pem

openssl req -new -key key.pem -out cert.csr

openssl x509 -req -in cert.csr -signkey key.pem -out cert.crt

openssl pkcs12 -export -in cert.crt -inkey key.pem -out cert.p12

上面命令行整理自https://stackoverflow.com/questions/21141215/creating-a-p12-file

[2019-05-18]webpack 指定多个静态文件夹

有一些资源, 基本不会发生改动, 所以并不想经过打包构建处理

这个时候一般可以指定一个存放这些静态资源的目录, 通过 webpack.devServer.contenBase 参数去指定

然后在 html 模板中直接引用, 而生产构建流程则要使用copy-webpack-plugin把静态目录 copy 到dist

大致配置如下

// webpack.devServer.contentBase
{
  // ...
  devServer: {
    contentBase: path.join(process.cwd(), "src/static");
  }
  // ...
  plugins: [
    // ...
    new CopyWebpackPlugin([
      {
        from: path.join(process.cwd(), "src/static"),
        to: path.join(process.cwd(), "dist"),
        ignore: [".*"]
      }
    ])
  ];
}
<!-- src/static/logo.png -->
<img src="<%= BASE_URL %>/logo.png" />

这里需要注意 webpack.devServer.contenBase 是可以指定多个目录的, 如

devServer: {
  contentBase: [
    path.join(process.cwd(), "src/static"),
    path.join(process.cwd(), "plugin")
  ];
}

如非必要的情况慎用此特性, 如果要使用就要小心维护避免两边出现同名文件

[2019-05-14]vue-cli 使用 npm script 指定配置文件路径, 在 windows 下不能正常识别

一开始使用 vue-cli 构建项目时, 使用下面的 npm script 去指定配置文件

scripts: {
  "serve": "VUE_CLI_SERVICE_CONFIG_PATH=$PWD vue-cli-service serve"
}

使用上面写法, 在 mac 平台下没有出现问题, 结果在 windows 下翻车了

首先想到的是通过命令设置process.env值时, 需要处理平台的兼容性, 就引入了cross-env

scripts: {
  "serve": "cross-env VUE_CLI_SERVICE_CONFIG_PATH=$PWD/build/vue.config.js vue-cli-service serve"
}

结果发现还是翻车了, 最终通过调试才发现, 原来 windows 下process.env中并没有PWD

所以写在 script 中的$PWD并没有正确解析成当前项目路径, 进而导致配置文件拼接错误

唯有把启动逻辑单独写了脚本, 再通过 npm script 调用, 最终改造如下

scripts: {
  "serve": "node ./script/run vue-cli-service serve"
}

// script/run.js
const path = require('path');
const crossEnv = require('cross-env');
const cwd = process.cwd();

const args = process.argv.slice(2);
const vueConfigDefault = process.env.VUE_CLI_SERVICE_CONFIG_PATH || './build/vue.config.js';

if (process.env.VUE_CLI_SERVICE_CONFIG_PATH) {
    args[0] = `VUE_CLI_SERVICE_CONFIG_PATH=${path.resolve(cwd, args[0].split('=')[1])}`;
} else {
    args.unshift(`VUE_CLI_SERVICE_CONFIG_PATH=${path.resolve(cwd, vueConfigDefault)}`);
}

crossEnv(args);
[2019-05-14]git 子模块相关命令
# 下载一个包含子模块的工程
git clone --recursive https://git.......

# 在已经下载的git仓库下更新子模块
git submodule update --init --recursive

# 添加子模块
git submodule add git://github.com/xxxx/yyyy.git path/to/place/submodule
[2019-05-11]vue-cli3.x 脚手架生成的项目, vue.config.js 使用 pages 配置多页应用时, 无法指定 template loader

在配置多页应用时指定 template 模板, 但是却在构建时却发现使用了 vue-cli 自带的模板, 使用vue inspect来检查生成的 webpack 配置时也的确是使用的自带模板

// vue.config.js
pages: {
    about: {
        entry: 'src/pages/about/index.js',
        template: `!!${path.resolve(__dirname, './lib/loader/html.js')}!${'about.shtml'}`,
        filename: 'about.shtml',
        chunks: ['chunk-vendors', 'chunk-common', 'about'],
        minify: false
    }
}

// 最终生成配置
new HtmlWebpackPlugin(
  {
    templateParameters: function () { /* omitted long function */ },
    chunks: [
      'chunk-vendors',
      'chunk-common',
      'about'
    ],
    template: '/path/to/node_modules/@vue/cli-service/lib/config/index-default.html',
    filename: 'about.shtml',
    minify: false
  }
)

@vue/cli-service源码时发现, 在配置html-webpack-plugin前, 会先检查 template 是否存在, 如果不存在的话会重新赋值成默认模板, 这里应该是检查template是否存在时出了问题

已经把 bug 反馈到vue-cli#3976

2019年5月31号更新, 该问题还没被修复, 不过可以通过chainWebpack对webpack插件配置进行改写, 愚蠢的我之前咋就没想到…..

const pages = {
  app: {
    entry: 'src/app.js',
    template: 'public/index.shtml'
  },
  about: {
    entry: 'src/about.js',
    template: 'public/about.shtml'
  }
};

module.exports = {
  pages: pages,
  chainWebpack: config => {
    Object.keys(pages).forEach(key => {
      config.plugin(`html-${key}`).tap(args => {
        if (!args || args.length === 0) return args;
        args[0].template = `!!/path/to/loader!${args[0].template}`;
        return args;
      });
    });
  }
}
[2019-05-10]webpack 使用动态加载import()引入的 ES6 模块, 需要通过 default 属性才能获取到模块内容
// m.js

export default function() {}

// webpack import()

import("./m").then(m => m()); // Uncaught (in promise) TypeError: m is not a function
import("./m")
  .then(m => m.default)
  .then(m => m()); // correct

这个其实是proposal-dynamic-import 规范定义的行为

简单来说import('module')代表的是import * as module from 'module', 而非import module from 'module'

相关 issue: proposal-dynamic-import#21, webpack#3829