Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow me to specify exactly which paths to load #1818

Closed
kiramclean opened this issue Nov 30, 2018 · 16 comments
Closed

Allow me to specify exactly which paths to load #1818

kiramclean opened this issue Nov 30, 2018 · 16 comments

Comments

@kiramclean
Copy link

Our webpacker config appears to be loading all of our test files and helpers for production builds. I need to exclude any files that end with .spec.ts now because since upgrading to rails 5.2.1 dev dependencies are no longer installed, which breaks the build since the spec files are looking for dev dependencies which aren't there. I do need to include any that end with just .ts, though (which are in the same directories as the ones with spec.ts, per angular community guidelines).

I see that webpacker automatically globs directories passed to resolved_paths, so I can't specify my own path there (i.e. the path I really want is app/assets/angular/**/*[^spec].ts, not just app/assets/angular/**/*). I also tried adding [^spec].ts to the extensions list, hoping webpacker would generate a path like app/assets/angular/**/*[^spec].ts, but it does not.

How do I tell webpacker to load only .ts files in app/assets/angular that do not end with spec.ts?

@jakeNiemiec
Copy link
Member

Do you link to any tests via entry points? Normally you would have a seperate webpack config that links to all the spec.ts files (or a central file that links to all spec.ts files). I remember back from my Angular days that it was especially finicky with tests.

As a stop-gap solution, consider moving your devDependencies to dependencies with minimal consequences (a longer yarn install). There's an active discussion on this over here: #1212 (comment)

@kiramclean
Copy link
Author

Thanks for the quick reply! I'm not 100% sure what you mean by "link to tests via entry points". We have two entry points for production builds, application.js and polyfills.js. I've run dependency graphs on both of those files and neither include any test dependencies.

As far as I understand how webpacker works, the separate webpack configs (including a separate one for dev/test that link to all the spec.ts files) are generated by the config in webpacker.yml, is that true?

So I guess my question is how do I tell webpacker in webpacker.yml exactly which files I want it to include for that environment?

I see how moving all of our dev dependencies to dependencies would solve this, but it seems like there should be a way to tell webpacker how to generate an environment-specific webpack config that only includes certain files. The only documentation I can find is this, which doesn't go into detail about how to use resolved_paths or extensions to build the kind of webpack config I'm after.

I need a development config that includes all .ts files, and a production config that excludes only .spec.ts files and files in specs/javascript. Greatly appreciate any insight you might have.

@jakeNiemiec
Copy link
Member

So I guess my question is how do I tell webpacker in webpacker.yml exactly which files I want it to include for that environment?

I must admit, I know more about Webpack than WebpackER. That being said, it sounds like WebpackER is eagerly loading your *.spec.ts files or you need a exclude: /\.spec\.ts$/ on one of your loaders (last one below). The only mechanism I could find that indicates eager loading is:

"Packs" is a special directory made only for webpack entry files so don't put anything here that you don't want to link in your views.

ts-loader/tsconfig could also have a missing exclude:

You could also be missing a needed exclude (exclude can be added for most loaders)

exclude: ["node_modules", /\.test\.ts$/]

Unfortunately that's all I got, hope it helps.

@kiramclean
Copy link
Author

kiramclean commented Nov 30, 2018

Thanks for the tips.. I've tried excluding specs in our tsconfig.json and in the typescript loader, but maybe there's something more to look into related to other loaders or somehow getting that config into a webpack config via webpacker.yml. I appreciate you answering questions like this was stack overflow! I'll close this since I haven't found a solution and don't plan on pursuing anything like a PR about it.

In case anyone else runs into the same issue,the workaround described here worked #440 (stopping webpacker from "enchancing" normal asset precompilation rake tasks), but we ended up just moving all of our dev dependencies to dependencies.

@Macrofig
Copy link

Macrofig commented Mar 15, 2019

I think I've run into a similar issue. We have a component folder structure like below:

  • cool-component (folder)
    • cool-component.jsx
    • cool-component.test.js
    • cool-component.md

I found that the Webpacker creates an entry property on the final webpack config with all my components, but instead of targeting the actual component, sometimes it selects the test file.

I've traced my problem to this area in the environments/base file. In some cases, the getEntryObject method targets my test file instead of the actual component entry file. Since my test file imports my component, production works fine; the bundles have what we need. Unfortunately, they also have unnecessary test code, too.

This is an example of what I get when I log the contents of entry:

{
  ... ,
  'components/cool-component/cool-component': '/some/root/folder/packs/components/cool-component/cool-component.test.js',
  ...
}

My guess is that it matched the jsx file then matched the test.js file and overwrote the correct path (the .jsx file).

I'm not sure how to solve this. One thought was adding an ignore pattern in the yml that getEntryObject could reference, i.e. \(/.test./)\. Another thought was to recreate getEntryObject in the webpack/environment.js file and properly build that entry object there but that might make upgrading difficult

I tried adding exclude conditions to the rules but that had no affect. I'm not that great with webpack and in debugging why the exclude didn't work, it lead me to the above findings.

My last option is to not use the yml at all and just create the webpack config myself. :(

Anyone else have thoughts on this?

@jakeNiemiec
Copy link
Member

I'm not sure how to solve this.

Just don't put your components under packs, you can place it in src or create a components folder that is directly under javascripts:

image

@Macrofig
Copy link

Oh. I totally misunderstood the intention of "packs". Derp. Thanks! :D

@JeremiahChurch
Copy link

JeremiahChurch commented Sep 20, 2019

I ran in to a similar situation - it's very common convention in the react community (and as I'm learning the JS community as a whole) to put test & other files next to the code rather than in a separate testing folder structure like in rails.

in my case I have:

/app/javascript/packs/
    application.js
/app/javascript/react/component/
    Component.jsx
    Component.test.js
    Component.stories.js

a simple add to config/webpack/production.js

environment.loaders.get('babel').exclude = [/\.test\.js$/, /\.stories\.js$/, environment.loaders.get('babel').exclude]

Has me back and working.

It would be slick to see this exposed in webpacker.yml as a configuration option as I'm sure all the different frameworks will need slightly different files excluded and doing it automatically as part of initial setup will save a lot of people that getting started headache.

@wileymc
Copy link

wileymc commented Dec 31, 2019

@JeremiahChurch I have the same file structure as you listed above and I was hoping your solution would work but I'm stilling seeing my react test files in the webpack analysis of the production build...any ideas?

@wileymc
Copy link

wileymc commented Dec 31, 2019

@JeremiahChurch I have the same file structure as you listed above and I was hoping your solution would work but I'm stilling seeing my react test files in the webpack analysis of the production build...any ideas?

I ended up having to use this nasty regex in my application.js pack

const componentRequireContext = require.context(
  "components",
  true,
  /^(?!.*(test.js$)).*\.(?:jsx|js)$/
);

@JeremiahChurch
Copy link

@JeremiahChurch I have the same file structure as you listed above and I was hoping your solution would work but I'm stilling seeing my react test files in the webpack analysis of the production build...any ideas?

@wileybaba Sorry that isn't working for you - I just checked that applications production config - that line is unchanged and still working.

I also just tested it in a much simpler default production.js file - as seen below - it looks to be working as expected as well.

process.env.NODE_ENV = process.env.NODE_ENV || 'production'

const environment = require('./environment')

environment.loaders.get('babel').exclude = [/\.test\.js$/, /\.stories\.js$/, environment.loaders.get('babel').exclude];

module.exports = environment.toWebpackConfig()

@ecbrodie
Copy link
Contributor

Adding in this comment to help benefit those working on projects that follow a standard of placing all frontend test code into nested __tests__/ directories. I used an adaptation of @wileybaba's solution, but just with an adjusted regex. This allows entire directories to be excluded, as opposed to just the test files themselves (I'm trying to consider files that aren't running tests directly, such as mock setup or test utility function files).

const componentRequireContext = require.context("components", true, /^(?!.*__tests__\/.*$).+\.[jt]sx?$/)

@akshaysmurthy
Copy link

@ecbrodie I wonder if using something like https://github.com/cherrry/ignore-loader would help.

@hbhanoo
Copy link

hbhanoo commented May 21, 2020

@akshaysmurthy +1. None of the other solutions worked for me. But adding the following to my config/webpack/production.js did the trick:

const ignoreTestFiles = {
  test: /test\.js$/,
  use: 'ignore-loader'
}

environment.loaders.append('ignoreTestFiles', ignoreTestFiles)

@ecbrodie
Copy link
Contributor

@akshaysmurthy that loader seems to be abandoned and only supports old webpack versions.

My solution has been in place on my webpacker project for months now without issue.

@rossta
Copy link
Member

rossta commented Jan 13, 2021

Based on this earlier comment I think we can close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants