Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Vue preset #484

Merged
merged 15 commits into from
Nov 29, 2017
Merged

Vue preset #484

merged 15 commits into from
Nov 29, 2017

Conversation

helfi92
Copy link
Member

@helfi92 helfi92 commented Nov 22, 2017

No description provided.

@helfi92 helfi92 self-assigned this Nov 22, 2017
@helfi92 helfi92 mentioned this pull request Nov 22, 2017
}, opts);

Object.defineProperty(options, 'extensions', {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eliperelman Let me know if this is the way you wanted it to be done. Once we've agreed on a way, I could update the rest neutrino to use it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in IRC, this can just be a normal property, and consumers can access the Set directly. We can also expose a method for generating a regex on the fly, but we don't want to limit this property to only creating regexes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing, a user should be able to pass this as an array to Neutrino options, which when merged using mergeOptions or whatever, can be merged with the Set values:

module.exports = {
  options: {
    extensions: ['vue']
  }
};

// ...

new Set([...this.options.extensions, ...extensions])

When merging we should also probably normalize the values to ensure they don't contain dots.

Time: 9773ms
Asset Size Chunks Chunk Names
index.dfbad882ab3d86bfd747.js 181 kB index [emitted] index
polyfill.57dabda41992eba7552f.js 69.2 kB polyfill [emitted] polyfill
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this polyfill line.


neutrino.config.when(neutrino.config.module.rules.has('lint'), () => neutrino.config.module
.rule('lint')
.test(neutrino.options.extensions)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the loader merge here:

neutrino.config.when(neutrino.config.module.rules.has('lint'), () => {
  neutrino.use(loaderMerge('lint', 'eslint'), {
    plugins: ['vue'],
    envs: ['node'],
    parserOptions: {
      ecmaFeatures: {
        jsx: true
      }
    },
    rules: {
      'vue/jsx-uses-vars': 2
    }
  });
});

"dependencies": {
"@neutrinojs/web": "^7.3.2",
"babel-preset-vue": "^1.2.1",
"deepmerge": "^1.4.4",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure where this version came from, but everywhere else it's at ^1.5.2.

"eslint-plugin-vue": "^2.1.0",
"stylelint-processor-html": "^1.0.0",
"vue-loader": "^13.5.0",
"vue-template-compiler": "^2.5.6"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a peerDependency of something? I don't see this used anywhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

module.exports = (neutrino, options) => {
neutrino.use(web, options);

neutrino.config.module.rule('vue')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use indented chaining when contexts change:

neutrino.config.module
  .rule('vue')
    .test(neutrino.options.extensions)
    .use('vue')
      .loader(require.resolve('vue-loader'))
      .options(options);

}, opts);

Object.defineProperty(options, 'extensions', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing, a user should be able to pass this as an array to Neutrino options, which when merged using mergeOptions or whatever, can be merged with the Set values:

module.exports = {
  options: {
    extensions: ['vue']
  }
};

// ...

new Set([...this.options.extensions, ...extensions])

When merging we should also probably normalize the values to ensure they don't contain dots.

@helfi92
Copy link
Member Author

helfi92 commented Nov 28, 2017

@eliperelman You mention here to have extensions merged i.e., new Set([...this.options.extensions, ...extensions]). I'm not sure why we need to merge the extensions. Sometimes you want to overwrite the entries instead of appending to the set. Let me know what you think about my last commit.

@eliperelman
Copy link
Member

I'm not sure why we need to merge the extensions. Sometimes you want to overwrite the entries instead of appending to the set.

I see this as being the primary use case:

module.exports = {
  options: {
    extensions: ['esm']
  }
};

Basically, a user can come in and add their own extensions, without having to replicate the whole list of other extensions that we store. Hence needing to merge instead of replace.

A replacement can still happen though if you're using the API, which seems good because I think it's a less common need, and only happens in more advanced cases:

neutrino.extensions = new Set(['js', 'jsx']);

* Expose a method for generating a regex from extensions
* Use indented chaining
* Use an updated version of the deepmerge package
@helfi92
Copy link
Member Author

helfi92 commented Nov 29, 2017

@eliperelman, In my last commit, something like the following:

module.exports = {
  options: {
    extensions: ['.vue', 'vue'],
  },
  ...
};

would make neutrino.options.extensions equal [ 'js', 'jsx', 'vue', 'ts', 'mjs', 'vue' ] whereas something like neutrino.options.extensions = ['vue'] overwrites the default extensions. Does it make more sense now? Thanks for your patience.

Copy link
Member

@eliperelman eliperelman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, I think we're close! Have you tested that merging extensions from .neutrinorc.js works correctly?

set(extensions) {
const newExtensions = extensions.map(ext => equals(ext[0], '.') ? tail(ext) : ext);

fileExtensions = [...new Set(newExtensions)];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the original value of fileExtensions is a Set, but here we spread it into an array. We can keep this as a Set here, and only spread to array during get:

fileExtensions = new Set(newExtensions);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combining this with my previous comment, this can be one-lined into:

fileExtensions = new Set(extensions.map(ext => ext.replace('.', '')));

return [...fileExtensions];
},
set(extensions) {
const newExtensions = extensions.map(ext => equals(ext[0], '.') ? tail(ext) : ext);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be simplified to:

const newExtensions = extensions.map(ext => ext.replace('.', ''));

@@ -26,14 +27,28 @@ const pathOptions = [

// getOptions :: Object? -> IO Object
const getOptions = (opts = {}) => {
let fileExtensions = new Set(['js', 'jsx', 'vue', 'ts', 'mjs']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename this to moduleExtensions so it's clear we are only dealing with module code instead of things like images and stylesheets.

@@ -87,6 +102,10 @@ class Api {
this.config = new Config();
}

regexFromExtensions(extensions = this.options.extensions) {
return new RegExp(`.(${extensions.join('|')})$`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️


module.exports = (neutrino, options) => {
neutrino.use(web, options);
neutrino.options.extensions = ['vue']; // eslint-disable-line no-param-reassign
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now have vue in the extensions list, so we don't need this line now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I include the js extension, I get an error:

ERROR in   Error: The loader "/Users/haali/Documents/Mozilla/projects/neutrino-dev/node_modules/html-webpack-plugin/lib/loader.js!/Use  rs/haali/Documents/Mozilla/projects/neutrino-dev/node_modules/html-webpack-template/index.ejs" didn't return html.

If extensions is something like ['jsx', 'vue', 'ts', 'mjs' ] (without the js extension), then it works. Do you know why this is happening?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, should we include .json in the list of extensions? :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this:

jantimon/html-webpack-plugin#602

Basically, I think the vue-loader is only supposed to accept vue extensions:

neutrino.config.module
    .rule('vue')
      .test(/\.vue$/) // instead of .test(neutrino.regexFromExtensions())
      .use('vue')
        .loader(require.resolve('vue-loader'))
        .options(options);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, should we include .json in the list of extensions? :)

I...don't know. Give it a shot and see if the tests continue to pass, but I'm not sure what effect it may have.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I figured, sounds good!

Btw, instead of hardcoding /\.vue$/, we could just do neutrino.regexFromExtensions(['vue']).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

const web = require('@neutrinojs/web');
const path = require('path');
const merge = require('deepmerge');
const loaderMerge = require('@neutrinojs/loader-merge');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move this require to be above the web one.

neutrino.config
.resolve
.modules.add(MODULES).end()
.extensions.add('.vue').end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make this automatic from the web preset:

neutrino.config.resolve.extensions.merge(neutrino.options.extensions.map(ext => `.${ext}`);

Something like that.

@helfi92
Copy link
Member Author

helfi92 commented Nov 29, 2017

@eliperelman Adding .json to the list of extensions seems to work. Added the requested changes. Hopefully, things are neater :) Once that is done, I could clean the other packages to use the list of extensions. Also, to answer your question, I have tested merging extensions from .neutrinorc.js. The example shown earlier was the one I tried on my machine.

const options = merge({
env: {
NODE_ENV: 'development'
},
debug: false,
quiet: false
quiet: false,
extensions: moduleExtensions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this line.

Copy link
Member

@eliperelman eliperelman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments.

Copy link
Member

@eliperelman eliperelman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 🌮 🎉

@helfi92 helfi92 merged commit 3d253ae into neutrinojs:master Nov 29, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

Successfully merging this pull request may close these issues.

3 participants